1. 基础形状操作
import numpy as np
# 创建一个示例数组
arr = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]])
print("原始数组:")
print(arr)
print("形状:", arr.shape)
2. reshape() - 重塑形状
# reshape 的基本使用
reshaped = arr.reshape(2, 6)
print("\nreshape(2, 6):")
print(reshaped)
# 使用 -1 自动计算维度
auto_reshaped = arr.reshape(-1, 2) # 自动计算行数
print("\nreshape(-1, 2):")
print(auto_reshaped)
# 展平为一维数组
flattened = arr.reshape(-1)
print("\n展平为一维数组:")
print(flattened)
3. resize() - 调整大小
# resize 会改变原始数组或返回新数组
resized = np.resize(arr, (2, 2))
print("\nresize((2, 2)):")
print(resized)
# 如果新形状更大,会重复数组元素
resized_larger = np.resize(arr, (4, 6))
print("\nresize((4, 6)) - 扩大:")
print(resized_larger)
4. flatten() 和 ravel() - 展平
# flatten() 返回副本
flattened_copy = arr.flatten()
flattened_copy[0] = 99 # 不影响原始数组
# ravel() 返回视图(如果可能)
raveled_view = arr.ravel()
raveled_view[0] = 100 # 会影响原始数组
print("\n原始数组(已被修改):")
print(arr)
print("\nflatten() 副本:")
print(flattened_copy)
5. transpose() 和 T - 转置
# 转置矩阵
transposed = arr.T
print("\n转置 arr.T:")
print(transposed)
# 使用 transpose() 可以指定轴顺序
arr_3d = np.arange(24).reshape(2, 3, 4)
print("\n3D数组:")
print(arr_3d.shape)
transposed_3d = arr_3d.transpose(1, 2, 0)
print("\ntranspose(1, 2, 0):")
print(transposed_3d.shape)
6. swapaxes() - 交换轴
# 交换两个轴
swapped = arr.swapaxes(0, 1)
print("\nswapaxes(0, 1):")
print(swapped)
print("形状:", swapped.shape)
# 3D数组交换轴
arr_3d = np.array([[[1, 2], [3, 4]],
[[5, 6], [7, 8]]])
print("\n3D数组形状:", arr_3d.shape)
# 交换轴 0 和 2
swapped_3d = arr_3d.swapaxes(0, 2)
print("swapaxes(0, 2) 形状:", swapped_3d.shape)
7. newaxis - 增加维度
# 使用 np.newaxis 增加维度
arr_1d = np.array([1, 2, 3, 4])
# 添加行维度(变为列向量)
col_vector = arr_1d[:, np.newaxis]
print("\n列向量:")
print(col_vector)
print("形状:", col_vector.shape)
# 添加列维度(变为行向量)
row_vector = arr_1d[np.newaxis, :]
print("\n行向量:")
print(row_vector)
print("形状:", row_vector.shape)
# 增加两个维度
arr_4d = arr_1d[np.newaxis, :, np.newaxis, np.newaxis]
print("\n增加多个维度:")
print("形状:", arr_4d.shape)
8. squeeze() - 移除单维度
# 移除长度为1的维度
arr_with_singleton = np.array([[[1], [2], [3]]])
print("\n原始数组形状:", arr_with_singleton.shape)
squeezed = np.squeeze(arr_with_singleton)
print("squeeze()后形状:", squeezed.shape)
# 指定移除特定维度
arr_3d = np.ones((1, 3, 1, 4))
print("\n原始形状:", arr_3d.shape)
squeezed_specific = np.squeeze(arr_3d, axis=0)
print("移除axis=0后形状:", squeezed_specific.shape)
9. stack(), hstack(), vstack(), dstack() - 堆叠
# 创建两个数组
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
# stack - 沿新轴堆叠
stacked = np.stack([a, b], axis=0)
print("\nstack(axis=0):")
print(stacked)
print("形状:", stacked.shape)
# hstack - 水平堆叠
h_stacked = np.hstack([a.reshape(-1, 1), b.reshape(-1, 1)])
print("\nhstack:")
print(h_stacked)
# vstack - 垂直堆叠
v_stacked = np.vstack([a, b])
print("\nvstack:")
print(v_stacked)
# dstack - 深度堆叠
d_stacked = np.dstack([a.reshape(1, -1), b.reshape(1, -1)])
print("\ndstack:")
print(d_stacked)
print("形状:", d_stacked.shape)
10. split(), hsplit(), vsplit() - 分割
# 分割数组
arr = np.arange(12).reshape(3, 4)
# split - 均匀分割
parts = np.split(arr, 3, axis=0)
print("\nsplit 成3部分:")
for i, part in enumerate(parts):
print(f"部分 {i}:")
print(part)
# hsplit - 水平分割
h_parts = np.hsplit(arr, 2)
print("\nhsplit 成2部分:")
for i, part in enumerate(h_parts):
print(f"部分 {i}:")
print(part)
# vsplit - 垂直分割
v_parts = np.vsplit(arr, 3)
print("\nvsplit 成3部分:")
for i, part in enumerate(v_parts):
print(f"部分 {i}:")
print(part)
11. tile() 和 repeat() - 重复
# tile - 平铺复制
arr = np.array([1, 2, 3])
tiled = np.tile(arr, (2, 3))
print("\ntile((2, 3)):")
print(tiled)
# repeat - 元素重复
repeated = np.repeat(arr, 3)
print("\nrepeat(3):")
print(repeated)
# 沿特定轴重复
arr_2d = np.array([[1, 2], [3, 4]])
repeated_axis = np.repeat(arr_2d, 2, axis=1)
print("\n沿axis=1重复2次:")
print(repeated_axis)
12. 实际应用示例
def batch_processing_example():
"""批量处理示例:将图像数据转换为适合神经网络输入的格式"""
# 模拟10张32x32的RGB图像
images = np.random.rand(10, 32, 32, 3)
print(f"原始图像形状: {images.shape}") # (10, 32, 32, 3)
# 重塑为适合全连接层的格式
flattened = images.reshape(10, -1)
print(f"展平后形状: {flattened.shape}") # (10, 3072)
# 转换为适合卷积层的格式
# 假设需要 (batch, channels, height, width) 格式
conv_format = images.transpose(0, 3, 1, 2)
print(f"卷积层格式: {conv_format.shape}") # (10, 3, 32, 32)
return flattened, conv_format
# 运行示例
flattened, conv_format = batch_processing_example()
重要注意事项:
视图 vs 副本:
reshape(), ravel(), T 返回视图(如果可能)
resize(), flatten() 返回副本
- 使用
arr.copy() 确保获得副本
内存连续性:
- 某些操作(如转置)会改变内存布局
- 使用
np.ascontiguousarray() 确保内存连续性
广播规则:
- NumPy 自动广播维度进行运算
- 了解广播规则可以避免不必要的 reshape
这些是 NumPy 形状操纵的核心功能,掌握它们能让你更高效地处理多维数据。