如何从Numpy矩阵的每一列获取一个值

5

我希望能够获取矩阵 M 中每一列中某个值的索引。例如:

M = matrix([[0, 1, 0],
            [4, 2, 4],
            [3, 4, 1],
            [1, 3, 2],
            [2, 0, 3]])

在伪代码中,我想要做这样的事情:

for col in M:
    idx = numpy.where(M[col]==0) # Only for columns!

让每一列的 idx 值分别为 040

我尝试使用 where,但我不理解返回值,它是一个矩阵元组。

5个回答

3

矩阵元组是适用于索引的项目集合。输出将具有索引矩阵(或数组)的形状,并且输出中的每个项目都将使用第一个数组作为第一维的索引,第二个数组作为第二维的索引,以此类推,从原始数组中选择。换句话说,这样做:

>>> numpy.where(M == 0)
(matrix([[0, 0, 4]]), matrix([[0, 2, 1]]))
>>> row, col = numpy.where(M == 0)
>>> M[row, col]
matrix([[0, 0, 0]])
>>> M[numpy.where(M == 0)] = 1000
>>> M
matrix([[1000,    1, 1000],
        [   4,    2,    4],
        [   3,    4,    1],
        [   1,    3,    2],
        [   2, 1000,    3]])

序列可能使您感到困惑。它按扁平化顺序进行--因此M [0,2]出现在第二位而不是第三位。如果您需要重新排序它们,您可以这样做:
>>> row[0,col.argsort()]
matrix([[0, 4, 0]])

您最好使用数组而不是矩阵。这样,您可以操纵数组的形状,这通常很有用!还要注意ajcr的转置技巧,这可能比使用argsort更可取。
最后,在这种情况下,还有一个nonzero方法与where执行相同的操作。现在使用转置技巧:
>>> (M == 0).T.nonzero()
(matrix([[0, 1, 2]]), matrix([[0, 4, 0]]))

2
作为 `np.where` 的替代方法,您可以尝试使用 `np.argwhere`,它会返回一个数组的索引,该数组符合条件。
>>> np.argwhere(M == 0)
array([[[0, 0]],

       [[0, 2]],

       [[4, 1]]])

这告诉你每个满足条件的索引的格式是[行, 列]

如果您更喜欢此输出数组的格式按列而不是按行分组(即[列, 行]),只需对数组的转置使用该方法:

>>> np.argwhere(M.T == 0).squeeze()
array([[0, 0],
       [1, 4],
       [2, 0]])

在这里我还使用了np.squeeze来消除轴1,以便我们只剩下一个2D数组。您想要的序列是第二列,即np.argwhere(M.T == 0).squeeze()[:, 1]


是的,你说得对,在这里使用转置比argsort更好。 - senderle

0

where(M == 0) 的结果看起来像这样

(matrix([[0, 0, 4]]), matrix([[0, 2, 1]])) 第一个矩阵告诉你哪些行有 0,第二个矩阵告诉你哪些列有 0

Out[4]: 
matrix([[0, 1, 0],
        [4, 2, 4],
        [3, 4, 1],
        [1, 3, 2],
        [2, 0, 3]])

In [5]: np.where(M == 0)
Out[5]: (matrix([[0, 0, 4]]), matrix([[0, 2, 1]]))

In [6]: M[0,0] 
Out[6]: 0

In [7]: M[0,2] #0th row 2nd column
Out[7]: 0

In [8]: M[4,1] #4th row 1st column
Out[8]: 0

0

这并不是什么新鲜事,已经有人提出了一行解决方案:

>>> np.where(np.array(M.T)==0)[-1]
array([0, 4, 0])

我同意NumPy matrix对象带来的麻烦比它们的价值更大。


0
>>> M = np.array([[0, 1, 0],
...             [4, 2, 4],
...             [3, 4, 1],
...             [1, 3, 2],
...             [2, 0, 3]])
>>> [np.where(M[:,i]==0)[0][0] for i in range(M.shape[1])]
[0, 4, 0]

2
虽然这可能是问题的正确解决方案,但建议您解释一下您的代码是如何工作的,以便提问者能够理解为什么您的解决方案有效,而不是盲目地复制粘贴它。 - SeinopSys

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接