为什么Python中向量的维数是(N,)而不是(N,1)?

问题描述 投票:0回答:4

在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))
那样重塑我的向量,但这可能会在后续代码中导致进一步的问题。

对此有什么建议吗?感谢您的帮助!

python numpy matrix vector tuples
4个回答
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)

因此,我建议您避免在代码中动态更改数组维度,除非您真的知道自己在做什么。相反,请为您要解决的问题选择最合适的数据结构,并确保您的输入和输出格式与该结构匹配。


0
投票

当 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)

此函数返回非向量矩阵的未更改维度,并添加描述第二个单位的附加维度,否则。


0
投票

感谢 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

0
投票

如果您想要一种方法,让您能够无差别地处理向量或矩阵,那么以下怎么样:

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)
© www.soinside.com 2019 - 2024. All rights reserved.