使用numpy.where()遍历矩阵

ShanZhengYang

有一些numpy.where()我不明白的地方:

假设我有一个2D numpy ndarray:

import numpy as np
twodim =  np.array([[1, 2, 3, 4],  [1, 6, 7, 8], [1, 1, 1, 12],  [17, 3, 15, 16], [17, 3, 18, 18]])

现在,想创建一个函数来“检查”此numpy数组的各种条件。

array([[ 1,  2,  3,  4],
       [ 1,  6,  7,  8],
       [ 1,  1,  1, 12],
       [17,  3, 15, 16],
       [17,  3, 18, 18]])

例如,此数组中的哪些条目的(A)偶数(B)大于7(C)除以3?

我想为此使用numpy.where(),并遍历此数组的每个条目,最后找到匹配所有条件的元素(如果存在这样的条目):

   even_entries = np.where(twodim % 2 == 0)
   greater_seven = np.where(twodim > 7 )
   divisible_three = np.where(twodim % 3 == 0)

如何做到这一点?我不确定如何遍历布尔值...

我可以通过访问矩阵(i,j)的索引

np.argwhere(even_entries)

我们可以做类似的事情

import numpy as np
twodim =  np.array([[1, 2, 3, 4],  [1, 6, 7, 8], [1, 1, 1, 12],  [17, 3, 15, 16], [17, 3, 18, 18]])
even_entries = np.where(twodim % 2 == 0)
greater_seven = np.where(twodim > 7 )
divisible_three = np.where(twodim % 3 == 0)
for row in even_entries:
    for item in row:
        if item: #equivalent to `if item == True`
                for row in greater_seven:
                    for item in row:
                        if item: #equivalent to `if item == True`
                            for row in divisible_three:
                                for item in row:
                                    if item: #equivalent to `if item == True`
                                        # something like print(np.argwhere())

有什么建议吗?

EDIT1:下面的好主意。正如@hpaulj提到的那样:“您的测试产生的布尔矩阵的形状与twodim相同”。这是我在玩耍时遇到的一个问题-并非所有条件生成的矩阵都与起始矩阵相同。例如,假设我正在比较array元素的左侧或右侧是否有匹配的数组(即水平)

twodim[:, :-1] == twodim[:, 1:]

结果是(5,3)布尔数组,而我们原来的矩阵是(5,4)数组

array([[False, False, False],
       [False, False, False],
       [ True,  True, False],
       [False, False, False],
       [False, False,  True]], dtype=bool)

如果我们在垂直方向上进行相同的操作,则将生成(4,4)布尔数组,而原始矩阵为(5,4)

twodim[:-1] == twodim[1:]

array([[ True, False, False, False],
       [ True, False, False, False],
       [False, False, False, False],
       [ True,  True, False, False]], dtype=bool) 

如果我们希望知道哪些条目既有垂直对又有水平对,那么弄清楚我们所处的维度是很重要的。

hpaulj

您的测试会产生一个与以下形状相同的布尔矩阵twodim

In [487]: mask3 = twodim%3==0
In [488]: mask3
Out[488]: 
array([[False, False,  True, False],
       [False,  True, False, False],
       [False, False, False,  True],
       [False,  True,  True, False],
       [False,  True,  True,  True]], dtype=bool)

如其他答案所述,您可以在逻辑上组合测试-和和或。

np.wherenp.nonzero(在此用法中)相同,只是返回True值的坐标-作为2个数组的元组。

In [489]: np.nonzero(mask3)
Out[489]: 
(array([0, 1, 2, 3, 3, 4, 4, 4], dtype=int32),
 array([2, 1, 3, 1, 2, 1, 2, 3], dtype=int32))

argwhere 返回相同的值,但作为转置的2d数组。

In [490]: np.argwhere(mask3)
Out[490]: 
array([[0, 2],
       [1, 1],
       [2, 3],
       [3, 1],
       [3, 2],
       [4, 1],
       [4, 2],
       [4, 3]], dtype=int32)

无论是masktuple可以直接用于索引你的数组:

In [494]: twodim[mask3]
Out[494]: array([ 3,  6, 12,  3, 15,  3, 18, 18])
In [495]: twodim[np.nonzero(mask3)]
Out[495]: array([ 3,  6, 12,  3, 15,  3, 18, 18])

argwhere不能直接用于索引,但可能更适合于反复,特别是如果你想索引以及价值观:

In [496]: for i,j in np.argwhere(mask3):
   .....:     print(i,j,twodim[i,j])
   .....:     
0 2 3
1 1 6
2 3 12
3 1 3
3 2 15
4 1 3
4 2 18
4 3 18

与相同的事情where需要一个zip

for i,j in zip(*np.nonzero(mask3)): print(i,j,twodim[i,j])

但是一般来说,numpy我们尽量避免迭代。如果您可以twodim[mask]直接使用您的代码,将会更快。

布尔掩码的逻辑组合比where索引的组合更容易产生要使用索引,我可能会求助于set操作(联合,相交,差异)。


对于缩减大小的测试,您必须决定如何将其映射到原始数组(和其他测试)。例如

(5,3)遮罩(列之间的差异):

In [505]: dmask=np.diff(twodim, 1).astype(bool)
In [506]: dmask
Out[506]: 
array([[ True,  True,  True],
       [ True,  True,  True],
       [False, False,  True],
       [ True,  True,  True],
       [ True,  True, False]], dtype=bool)

它可以索引原始数组的3列

In [507]: twodim[:,:-1][dmask]
Out[507]: array([ 1,  2,  3,  1,  6,  7,  1, 17,  3, 15, 17,  3])
In [508]: twodim[:,1:][dmask]
Out[508]: array([ 2,  3,  4,  6,  7,  8, 12,  3, 15, 16,  3, 18])

它也可以与其他遮罩的3列组合:

In [509]: dmask & mask3[:,:-1]
Out[509]: 
array([[False, False,  True],
       [False,  True, False],
       [False, False, False],
       [False,  True,  True],
       [False,  True, False]], dtype=bool)

以布尔数组形式组合测试比通过where索引组合起来要容易得多

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

遍历numpy中的矩阵

来自分类Dev

循环遍历 numpy 矩阵元素

来自分类Dev

如何使用接口信号遍历numpy矩阵?

来自分类Dev

使用迭代器遍历boost :: ublas矩阵

来自分类Dev

使用BFS遍历2D矩阵

来自分类Dev

使用循环遍历列表中存储的矩阵

来自分类Dev

Numpy.where 使用

来自分类Dev

使用numpy快速遍历像素

来自分类Dev

使用稀疏矩阵与numpy数组

来自分类Dev

使用 numpy 生成特定矩阵

来自分类Dev

Numpy在二维矩阵上的where()

来自分类Dev

Numpy在二维矩阵上的where()

来自分类Dev

numpy.where的嵌套使用

来自分类常见问题

numpy:如何使用矩阵元素作为索引?

来自分类Dev

优化numpy矩阵运算(当前使用for循环)

来自分类Dev

使用numpy加速多矩阵产品

来自分类Dev

使用numpy数组进行矩阵乘法

来自分类Dev

使用Numpy生成N维矩阵

来自分类Dev

不使用numpy计算协方差矩阵

来自分类Dev

使用numpy进行类似的矩阵计算

来自分类Dev

numpy:如何使用矩阵元素作为索引?

来自分类Dev

使用numpy的矩阵martix中的元素总和

来自分类Dev

使用NumPy和pandas的Python文本矩阵

来自分类Dev

优化numpy矩阵运算(当前使用for循环)

来自分类Dev

避免使用numpy矩阵进行for循环

来自分类Dev

使用 numpy 在 python 中迭代矩阵

来自分类Dev

如何使用 numpy 矩阵构建 newtworkx 图?

来自分类Dev

使用numpy将点矩阵上的矩阵相乘?

来自分类Dev

NumPy-使用强度值矩阵的图像(矩阵)阈值。