遍历 NumPy 矩阵列表

Iterate over list of NumPy matrices

我有一个包含行矩阵的列表:

rows = [ matrix([[1, 0, 0]]), matrix([[0, 1, 0]]), matrix([[0, 0, 1]]) ]

我尝试使用 for (a, b, c) in rows: 遍历这些,但我没有这样做,而是收到一个错误:

ValueError: not enough values to unpack (expected 3, got 1)

预期的行为是将行中的三个元素解包为 a, b, c:

for (a, b, c) in rows:
    print(f"{a} {b} {c}")
> 1 0 0
> 0 1 0
> 0 0 1

不幸的是,这适用于 [1, 0, 0],但不适用于 [[1, 0, 0]]

我意识到这是因为它们是 [[doubly packed]],但我想知道是否有解决此问题的简单方法?

您似乎想解压每个矩阵本身。在那种情况下,我会建议:不要使用 matrix 或 NumPy。也根本没有理由使用 NumPy 矩阵。甚至 NumPy documentation 也声明您应该更喜欢数组而不是矩阵。但在这种情况下,您应该使用普通列表,如果您遍历它们或解压缩它们,它们会更快。

因此,您首先要遍历每个矩阵,然后要解压缩其中的每一个。但是你必须分两步完成:

for mat in rows:      # this iterates over the list and gives you each matrix
    # this unpacks the matrix
    # to make it work faster I converted it to a list first using "tolist"
    # note that I needed to index it because it's a 2D matrix!
    a, b, c = mat.tolist()[0]
    print(a, b, c)  

也可以在一行中执行两个步骤:

for a, b, c in (mat.tolist()[0] for mat in rows):
    print(a, b, c)

一个问题是索引矩阵的一行仍然会给出一个矩阵。一种解决方法是将矩阵转换为一维数组:

In [368]: for r in rows:
     ...:     a,b,c=r.A1
     ...:     print(a,b,c)
     ...:     
1 0 0
0 1 0
0 0 1

Numpy matrix to array


In [370]: for r in rows:
     ...:     print(r.shape,r[0].shape)
     ...:     
(1, 3) (1, 3)
(1, 3) (1, 3)
(1, 3) (1, 3)

我通常不使用也不推荐从数组中解包值。这与数组的通用性背道而驰。拆包(除非使用“*”术语)会修复尺寸。但一般来说,数组可以有多个维度,而且尺寸很大。

np.matrix不鼓励。如果这些元素是 np.array 而不是,就不会有这个持久的二维问题。

因为我们使用 a,b,c 从每个矩阵的第一行中提取元素,似乎我们保证每行有 3 个元素,并且对于这些矩阵中的每一个,每行一个。因此,一个简单的解决方案(如所要求的)是在使用循环时使用数组构造函数并挤出单例嵌套级别,就像这样 -

for a,b,c in np.array(rows)[:,0]:

或更简单的np.squeeze() -

for a,b,c in np.squeeze(rows):

请注意,这不是内存效率最高的方法,而是一种提取所需标量值的简单方法。

这是一个示例 运行 -

In [375]: for a,b,c in np.squeeze(rows):
     ...:     print(a,b,c)
     ...:     
(1, 0, 0)
(0, 1, 0)
(0, 0, 1)