迭代NumPy矩阵列表

时间:2017-09-07 20:48:26

标签: python numpy for-loop matrix iterable-unpacking

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

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]],但我想知道这个问题是否有一个简单的解决方案?

3 个答案:

答案 0 :(得分:2)

好像你想解压每个矩阵本身。在这种情况下,我会建议:不要使用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)

答案 1 :(得分:2)

问题在于索引矩阵的行仍然给出矩阵。解决这个问题的方法是将矩阵转换为1d数组:

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而不是这种持续的2d问题。

答案 2 :(得分:2)

因为我们使用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)