趋近智
为了在数值计算中有效使用 NumPy 数组,了解它们的结构并知道如何修改它至关重要。每个 NumPy 数组都带有内置的特性,称为属性,它们描述了数组的特点。了解这些属性对于调试、理解内存使用以及为机器学习 (machine learning)算法准备数据都很有用。这还涵盖了如何在不改变数组底层数据的情况下改变其形状,这是数据处理中的一个常见要求。
NumPy 数组有一些有用的属性,可以提供关于数组本身的信息。这些属性使用点表示法访问(例如,my_array.attribute_name)。以下是一些最常用的属性:
ndarray.ndim:此属性指示数组的维度数量(或轴数)。向量 (vector)(例如 [1, 2, 3])有 1 个维度,而矩阵(例如 [[1, 2], [3, 4]])有 2 个维度。ndarray.shape:这提供了一个元组,指示数组在每个维度上的大小。对于一个包含 3 个元素的一维数组,shape 将是 (3,)。对于一个包含 2 行 4 列的二维数组(矩阵),shape 将是 (2, 4)。ndarray.size:这表示数组中元素的总数。它就是 shape 元组中数字的乘积。对于形状为 (2, 4) 的数组,size 为 。ndarray.dtype:这指定了数组中存储元素的数据类型。常见类型包括 int64(64 位整数)、float64(64 位浮点数)和 bool(布尔值)。数据类型会影响数组使用的内存量和计算的精度。让我们看看这些属性如何使用。
import numpy as np
# 创建一个一维数组(向量)
vec = np.array([10, 20, 30, 40])
# 创建一个二维数组(矩阵)
mat = np.array([[1.5, 2.5, 3.5],
[4.5, 5.5, 6.5]])
print("向量:")
print(f" 数据: {vec}")
print(f" 维度数量 (ndim): {vec.ndim}")
print(f" 形状: {vec.shape}")
print(f" 元素总数 (size): {vec.size}")
print(f" 数据类型 (dtype): {vec.dtype}")
print("\n矩阵:")
print(f" 数据:\n{mat}")
print(f" 维度数量 (ndim): {mat.ndim}")
print(f" 形状: {mat.shape}")
print(f" 元素总数 (size): {mat.size}")
print(f" 数据类型 (dtype): {mat.dtype}")
输出:
向量:
数据: [10 20 30 40]
维度数量 (ndim): 1
形状: (4,)
元素总数 (size): 4
数据类型 (dtype): int64
矩阵:
数据:
[[1.5 2.5 3.5]
[4.5 5.5 6.5]]
维度数量 (ndim): 2
形状: (2, 3)
元素总数 (size): 6
数据类型 (dtype): float64
请注意,一维数组 vec 的 shape 是 (4,),表示一个长度为 4 的维度。二维数组 mat 的 shape 是 (2, 3),表示 2 个维度(行和列),长度分别为 2 和 3。size 是元素的总数,dtype 反映了创建时使用的数字类型(vec 为 int,mat 为 float)。
通常,你的数据可能是一种形状,但需要将其转换为另一种形状。例如,你可能有一个来自图像的像素值长列表(一维),你希望将其排列成代表图像高度和宽度的网格(二维)。NumPy 提供了函数来调整数组形状而不改变其数据内容。
实现此目的主要方法是 reshape() 函数。
ndarray.reshape(new_shape)
此方法返回一个新数组,其数据与原始数组相同,但按 new_shape 排列。重要规则是元素总数 (size) 必须保持不变。你不能将一个大小为 6 的数组调整为需要 7 个元素的形状。
# 创建一个包含 12 个元素的一维数组
data = np.arange(12) # 创建数组 [0, 1, ..., 11]
print(f"原始数组(形状 {data.shape}):\n{data}")
# 调整为 3x4 矩阵
matrix_3x4 = data.reshape((3, 4))
print(f"\n调整为 3x4(形状 {matrix_3x4.shape}):\n{matrix_3x4}")
# 调整为 4x3 矩阵
matrix_4x3 = data.reshape((4, 3))
print(f"\n调整为 4x3(形状 {matrix_4x3.shape}):\n{matrix_4x3}")
# 调整为 2x6 矩阵
matrix_2x6 = data.reshape((2, 6))
print(f"\n调整为 2x6(形状 {matrix_2x6.shape}):\n{matrix_2x6}")
# 尝试进行无效的形状调整
try:
invalid_shape = data.reshape((3, 5)) # 3 * 5 = 15,原始大小为 12
except ValueError as e:
print(f"\n调整为 (3, 5) 时出错:{e}")
输出:
原始数组(形状 (12,)):
[ 0 1 2 3 4 5 6 7 8 9 10 11]
调整为 3x4(形状 (3, 4)):
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
调整为 4x3(形状 (4, 3)):
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
调整为 2x6(形状 (2, 6)):
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
调整为 (3, 5) 时出错:cannot reshape array of size 12 into shape (3,5)
请注意,元素是如何按行填充新形状的。尝试将形状调整为 (3, 5) 失败,因为 ,这与原始的 size 12 不匹配。
-1 推断维度有时,你只知道除一个维度外的所有维度的大小。你可以在 reshape 元组中使用 -1 作为占位符,NumPy 会根据元素总数自动计算该维度的正确大小。
data = np.arange(12) # 数组 [0, 1, ..., 11]
# 调整为 2 行,自动计算列数
matrix_2_rows = data.reshape((2, -1))
print(f"调整为 (2, -1) -> 形状 {matrix_2_rows.shape}:\n{matrix_2_rows}")
# 调整为 4 列,自动计算行数
matrix_4_cols = data.reshape((-1, 4))
print(f"\n调整为 (-1, 4) -> 形状 {matrix_4_cols.shape}:\n{matrix_4_cols}")
输出:
调整为 (2, -1) -> 形状 (2, 6):
[[ 0 1 2 3 4 5]
[ 6 7 8 9 10 11]]
调整为 (-1, 4) -> 形状 (3, 4):
[[ 0 1 2 3]
[ 4 5 6 7]
[ 8 9 10 11]]
在第一个例子中,NumPy 计算出要在 2 行中容纳 12 个元素,它需要 列。在第二个例子中,它计算出 行。这种使用 -1 的方法非常方便。
这是将一个包含 12 个元素的一维数组使用
reshape((3, 4))调整为 3 行 4 列的二维数组的示意图。元素的总数仍为 12。
将多维数组调整为一维数组的逆向操作称为展平:即将多维数组转换为一维数组。ravel() 方法常用于此目的。
ndarray.ravel()
此方法返回一个展平的一维数组,其中包含原始数组的所有元素。如果可能,它通常返回原始数组的视图,这意味着它不会在内存中创建数据的副本,从而非常高效。
matrix = np.array([[1, 2, 3],
[4, 5, 6]])
print(f"原始矩阵(形状 {matrix.shape}):\n{matrix}")
# 展平矩阵
flattened_array = matrix.ravel()
print(f"\n展平数组(形状 {flattened_array.shape}):\n{flattened_array}")
输出:
原始矩阵(形状 (2, 3)):
[[1 2 3]
[4 5 6]]
展平数组(形状 (6,)):
[1 2 3 4 5 6]
ravel() 方法按行读取元素以创建一维数组。
了解 shape、size 和 dtype 等数组属性,以及掌握如何使用 reshape 和 ravel 调整 shape,是高效使用 NumPy 的基本能力。这些操作在为机器学习 (machine learning)模型准备输入数据或解析线性代数计算结果时经常用到。
这部分内容有帮助吗?
© 2026 ApX Machine Learning用心打造