numpy 是否有数组方法可以测试多个相等值?

rseugnpd  于 2023-01-09  发布在  其他
关注(0)|答案(3)|浏览(128)

我想知道数组a在哪里等于数组b中的任何一个值。
例如,

a = np.random.randint(0,16, size=(3,4))
b = np.array([2,3,9])

# like this, but for any size b:
locations = np.nonzero((a==b[0]) | (a==b[1]) | (a==b[3]))

原因是我可以将a中的值从(b中的任何一个)更改为另一个值:

a[locations] = 99

对相等性检查进行或运算并不是一个很好的解决方案,因为我想在不事先知道b的大小的情况下进行运算,有数组解决方案吗?
[编辑]现在这个问题有两个很好的答案,一个使用额外维度的广播,另一个使用np.in1d。这两个都适用于这个问题的特定情况。我最终使用np.isin代替,因为它似乎对ab的形状更不可知。
我接受了教给我关于in1d的答案,因为它引导我找到了我更喜欢的解决方案。

sulc1iza

sulc1iza1#

您可以使用np.in1d,然后使用reshape返回到a的形状,这样您就可以将a中的值设置为您的特殊标志。

import numpy as np
np.random.seed(410012)

a = np.random.randint(0, 16, size=(3, 4))
#array([[ 8,  5,  5, 15],
#       [ 3, 13,  8, 10],
#       [ 3, 11,  0, 10]])

b = np.array([[2,3,9], [4,5,6]])
a[np.in1d(a, b).reshape(a.shape)] = 999
#array([[  8, 999, 999,  15],
#       [999,  13,   8,  10],
#       [999,  11,   0,  10]])
jvlzgdj9

jvlzgdj92#

对等式检查进行或运算并不是一个很好的解决方案,因为我想在不提前知道b的大小的情况下做这个。

编辑:

矢量化后的代码等同于你上面写的代码-

a = np.random.randint(0,16, size=(3,4))
b = np.array([2,3,9])

locations = np.nonzero((a==b[0]) | (a==b[1]) | (a==b[2]))

locations2 = np.nonzero((a[None,:,:]==b[:,None,None]).any(0))

np.allclose(locations, locations2)
True

这表明您的输出与这个输出完全相同,而不需要显式地提到b[0], b[1]...或使用for循环。

解释-

1.在这种情况下,广播一个操作可以帮助您。您尝试做的是将每个(3,4)矩阵元素与b中的每个值(3,)进行比较。这意味着所需的结果布尔矩阵将是三个(3,4)矩阵,即(3,3,4)
1.一旦你完成了,你需要在三个(3,4)矩阵元素之间取一个ANYOR,这将把(3,3,4)减少到(3,4)
1.最后,您需要使用np.nonzero来标识值等于TRUE的位置
以上3个步骤可按以下方法进行-

  • 播出比较操作:
a[None,:,:]==b[:,None,None]] #(1,3,4) == (3,1,1) -> (3,3,4)
  • 使用OR逻辑减少:
(a[None,:,:]==b[:,None,None]).any(0)  #(3,3,4) -> (3,4)
  • 获取非零位置:
np.nonzero((a[None,:,:]==b[:,None,None]).any(0))
gkn4icbw

gkn4icbw3#

numpy.isin适用于多维的ab

In [1]: import numpy as np

In [2]: a = np.random.randint(0, 16, size=(3, 4)); a
Out[2]:
array([[12,  2, 15, 11],
       [12, 15,  5, 10],
       [ 4,  2, 14,  7]])

In [3]: b = [2, 4, 5, 12]

In [4]: c = [[2, 4], [5, 12]]

In [5]: np.isin(a, b).astype(int)
Out[5]:
array([[1, 1, 0, 0],
       [1, 0, 1, 0],
       [1, 1, 0, 0]])

In [6]: np.isin(a, c).astype(int)
Out[6]:
array([[1, 1, 0, 0],
       [1, 0, 1, 0],
       [1, 1, 0, 0]])

In [7]: a[np.isin(a, b)] = 99; a
Out[7]:
array([[99, 99, 15, 11],
       [99, 15, 99, 10],
       [99, 99, 14,  7]])

相关问题