在Python中,我正在编写代码,在某些时候,处理矩阵(可能是向量)
X
并考虑其维度。我想将每个维度分别存储在变量 m
和 n
中。
如果矩阵
X
是大小为 N x 1
的向量,则 np.shape(X)
将返回输出为 (N,)
。但是,此信息没有帮助,因为当我将其存储为 m,n = np.shape(X)
时,我遇到错误:
ValueError: not enough values to unpack (expected 2, got 1)
有人知道如何解决这个问题吗?理想情况下,我想存储
m = N, n = 1
,但我不知道如何实现这一点。我考虑过像 X = np.reshape(X, (np.shape(X)[0], 1))
那样重塑我的向量,但这可能会在后续代码中导致进一步的问题。
对此有什么建议吗?感谢您的帮助!
检查 Numpy 数组维数的最简单方法就是在数组上使用
ndim
属性。例如,在 Python 控制台:
>>> import numpy as np
>>> a = np.array([1, 2, 3])
>>> a.ndim
1
>>> b = np.array([[1, 2, 3], [4, 5, 6]])
>>> b.ndim
2
您可以使用它在向量/一维和矩阵/二维数组处理之间切换逻辑:
def process(X):
if X.ndim == 1:
# ... vector processing ...
elif X.ndim == 2:
# ... matrix processing ...
else:
raise ValueError(f"Too many dimensions: {X.ndim}")
需要记住的一件事是,Numpy(以及 Python 的底层数组结构)在单维数组和二维数组之间存在区别,其中一个维度的长度为 1。
因此,维度为
(N)
的数组(在 Python 输出中表示为 (N,)
)与维度为 (N, 1)
或 (1, N)
的数组不同。一些例子来说明:
>>> np.shape([1, 2, 3])
(3,)
>>> np.shape([[1], [2], [3]])
(3, 1)
>>> np.shape([[1, 2, 3]])
(1, 3)
因此,我建议您避免在代码中动态更改数组维度,除非您真的知道自己在做什么。相反,请为您要解决的问题选择最合适的数据结构,并确保您的输入和输出格式与该结构匹配。
当 NumPy 处理一维数组或向量并返回包含单个元素的元组时,它以
(5,)
格式呈现,而不仅仅是 (5)
。这种在值后面加逗号的格式(例如 (5,)
)用于指示它是一个元组,而不仅仅是一个没有括号的值。
当
np.shape(X)
返回一维数组的单元素元组时,就会出现问题。尝试解包(例如 m, n = np.shape(X)
)会触发错误,因为 Python 需要两个值来解包,但只收到一个值,从而导致“没有足够的值来解包”错误。
为了避免此问题,可以利用
np.shape(X)
方法来确定数组维度中的元素数量,并根据需要添加必要的维度。
这是解决此问题的示例函数:
def dim(matrix, required_dims=2):
shape = np.shape(matrix)
if len(shape) < required_dims:
shape += (1,) * (required_dims - len(shape))
return shape
此函数根据
shape
将所需的维数添加到 required_dims
元组中,即使对于一维数组也能确保正确的维数。
使用示例:
matrix = np.array([1, 2, 3, 4, 5])
result = dim(matrix, required_dims=3)
print(result) # Output: (5, 1, 1)
对于您的情况,您可以使用:
m, n = dim(matrix)
如果需要,您可以删除此函数中的条件
if
语句:
def dim(matrix, required_dims=2):
shape = np.shape(matrix)
shape += (1,) * (required_dims - len(shape))
return shape
如果你只需要处理向量,可以使用这个函数:
def dim(matrix):
shape = np.shape(matrix)
return shape if len(shape) > 1 else (shape[0], 1)
此函数返回非向量矩阵的未更改维度,并添加描述第二个单位的附加维度,否则。
感谢 AKX 的提示。
通过使用
np.expand_dims
,您可以避免在尝试解压向量的维度时遇到的错误。具体方法如下:
import numpy as np
# Your vector X
X = np.array([1, 2, 3, 4]) # Example vector, replace it with your own
print("X:", X)
# Obtaining dimensions using np.shape
shape = np.shape(X)
print("X shape:", shape)
# Checking if X is a vector
if len(shape) == 1:
# If it's a vector, add a new axis
X = np.expand_dims(X, axis=1) # Adding a second dimension axis
print("Expanded X:", X)
print("Expanded X shape:", np.shape(X))
# Now the dimensions can be unpacked without errors
m, n = np.shape(X)
# Displaying the results
print("m =", m) # Number of rows
print("n =", n) # Number of columns (in this case for a vector, it will be 1)
此代码验证
X
是否为向量(即,是否具有一维),如果是,则使用 np.expand_dims
引入一个新轴。
代码的输出:
X: [1 2 3 4]
X shape: (4,)
Expanded X: [[1]
[2]
[3]
[4]]
Expanded X shape: (4, 1)
m = 4
n = 1
请注意,使用这种方法,访问向量内的元素将需要两次索引操作:
print(X[0]) # Output - an array consisting of one element
print(X[0][0]) # You can obtain the element like this
print(X[0, 0]) # or like this
输出:
[1]
1
1
如果您想要一种方法,让您能够无差别地处理向量或矩阵,那么以下怎么样:
m, n, *_ = (*X.shape, 1)
平面数组的示例
>>> X = np.arange(10)
>>> m, n, *_ = (*X.shape, 1) # <-- The approach
>>> m, n
(10, 1)
矩形矩阵的示例
>>> X = np.arange(12).reshape((3, 4))
>>> m, n, *_ = (*X.shape, 1) # <-- The approach
>>> m, n
(3, 4)