NumPy 是 Python 中用于数值计算的核心库,其多维数组功能是数据科学和工程计算的基础。在实际工作中,我们经常需要根据需求对数组进行形状重构,例如调整维度、添加或删除轴等。NumPy 提供了强大的数组重构工具,如 reshape
、ravel
、resize
等,可以灵活高效地处理数组形状。
在 NumPy 中,数组的形状由一个元组表示,描述了数组在每个维度上的大小。例如,一个形状为 (3, 4)
的数组表示有 3 行 4 列。
使用 shape
属性可以查看数组的形状:
import numpy as np
# 创建一个二维数组
arr = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
print("数组:\n", arr)
print("数组形状:", arr.shape)
输出:
数组:
[[1 2 3]
[4 5 6]
[7 8 9]]
数组形状: (3, 3)
reshape
:创建一个具有新形状的数组。resize
:直接修改数组的形状。ravel
和 flatten
:将多维数组展平成一维。reshape
方法用于创建一个新形状的数组,而不会改变原始数据。新形状必须与原数组的元素总数一致。
# 创建一个一维数组
arr = np.arange(12)
# 将数组重构为 3 行 4 列
reshaped_arr = arr.reshape(3, 4)
print("重构后的数组:\n", reshaped_arr)
输出:
重构后的数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
reshape
支持使用 -1
让 NumPy 自动计算某一维的大小:
# 自动计算列数
reshaped_arr = arr.reshape(3, -1)
print("自动计算维度的数组:\n", reshaped_arr)
输出:
自动计算维度的数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
在这个例子中,NumPy 根据总元素数量和指定的行数自动计算列数。
与 reshape
不同,resize
会直接修改原数组的形状,并允许调整元素数量。
# 使用 resize 修改数组形状
arr = np.arange(12)
arr.resize(3, 4)
print("调整形状后的数组:\n", arr)
输出:
调整形状后的数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
如果新形状的大小与原数组的元素数量不一致,resize
会用默认值填充或裁剪多余的部分:
# 扩展数组
arr.resize(4, 4)
print("扩展后的数组:\n", arr)
# 裁剪数组
arr.resize(2, 4)
print("裁剪后的数组:\n", arr)
输出:
扩展后的数组:
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]
[ 0 0 0 0]]
裁剪后的数组:
[[0 1 2 3]
[4 5 6 7]]
将多维数组展平成一维数组是常见的操作,ravel
和 flatten
都能实现这一功能,但它们有一些区别:
ravel
返回的是原数组的视图,修改会影响原数组。flatten
返回的是原数组的副本,修改不会影响原数组。arr = np.array([[1, 2, 3], [4, 5, 6]])
# 使用 ravel 展开数组
ravelled = arr.ravel()
ravelled[0] = 99
print("使用 ravel 展开后的数组:", ravelled)
print("原数组:\n", arr)
# 使用 flatten 展开数组
flattened = arr.flatten()
flattened[0] = 100
print("使用 flatten 展开后的数组:", flattened)
print("原数组:\n", arr)
输出:
使用 ravel 展开后的数组: [99 2 3 4 5 6]
原数组:
[[99 2 3]
[ 4 5 6]]
使用 flatten 展开后的数组: [100 2 3 4 5 6]
原数组:
[[99 2 3]
[ 4 5 6]]
可以看到,ravel
修改了原数组,而 flatten
则不会影响原数组。
可以通过 np.newaxis
或 expand_dims
方法为数组添加新轴:
arr = np.array([1, 2, 3])
# 添加一个新轴
expanded = arr[:, np.newaxis]
print("添加新轴后的数组:\n", expanded)
输出:
添加新轴后的数组:
[[1]
[2]
[3]]
可以使用 squeeze
方法删除大小为 1 的轴:
arr = np.array([[[1], [2], [3]]])
# 删除大小为 1 的轴
squeezed = np.squeeze(arr)
print("删除新轴后的数组:", squeezed)
通过 transpose
或 .T
可以实现数组的转置:
arr = np.array([[1, 2], [3, 4], [5, 6]])
# 转置数组
transposed = arr.T
print("转置后的数组:\n", transposed)
输出:
转置后的数组:
[[1 3 5]
[2 4 6]]
在图像处理或深度学习中,常常需要对数组形状进行重构。例如,将多个图像的数据从形状 (batch, height, width, channels)
转换为 (batch, channels, height, width)
。
# 模拟图像数据
images = np.random.rand(10, 64, 64, 3)
# 调整形状
reshaped_images = images.transpose(0, 3, 1, 2)
print("调整后的图像数据形状:", reshaped_images.shape)
输出:
调整后的图像数据形状: (10, 3, 64, 64)
通过重构数组形状,可以更好地适配深度学习模型的输入格式。
NumPy 提供了灵活强大的工具来调整数组形状,从 reshape
到 ravel
,从添加轴到删除轴,每种方法都有其独特的应用场景。通过掌握这些操作,可以轻松应对各种复杂的数据处理任务。在实际工作中,合理选择数组形状重构方法,不仅可以提高代码的可读性,还能显著提升程序性能。
如果你觉得文章还不错,请大家 点赞、分享、留言 下,因为这将是我持续输出更多优质文章的最强动力!