17

我有一个整数数组,想找到该数组等于多个值列表中的任何值的位置。

这可以通过单独处理每个值或在循环中使用多个“或”语句来轻松完成,但我觉得必须有更好/更快的方法来做到这一点。我实际上正在处理 size 的数组4000 x 2000,但这是问题的简化版本:

fake = arange(9).reshape((3,3))

array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])

want = (fake==0) + (fake==2) + (fake==6) + (fake==8)

print want 

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

我想要的是一种从涉及和值列表的want单个命令中获取的方法。fake[0, 2, 6, 8]

我假设有一个包已经包含了这个,这比我在 Python 中编写一个带有循环的函数要快得多。

4

3 回答 3

17

函数numpy.in1d似乎做你想做的事。唯一的问题是它只适用于一维数组,所以你应该像这样使用它:

In [9]: np.in1d(fake, [0,2,6,8]).reshape(fake.shape)
Out[9]: 
array([[ True, False,  True],
       [False, False, False],
       [ True, False,  True]], dtype=bool)

我不知道为什么这仅限于一维数组。查看它的源代码,它首先似乎将两个数组展平,然后它做了一些巧妙的排序技巧。但是没有什么能阻止它在最后再次弄平结果,就像我必须在这里手工做的那样。

于 2013-10-23T18:37:22.390 回答
11

NumPy 0.13+

从 NumPy v0.13 开始,您可以使用np.isin,它适用于多维数组:

>>> element = 2*np.arange(4).reshape((2, 2))
>>> element
array([[0, 2],
       [4, 6]])
>>> test_elements = [1, 2, 4, 8]
>>> mask = np.isin(element, test_elements)
>>> mask
array([[ False,  True],
       [ True,  False]])

NumPy 0.13 之前

接受的答案np.in1d仅适用于一维数组,并且需要重新整形以获得所需的结果。这适用于 v0.13 之前的 NumPy 版本。

于 2018-10-03T14:57:29.460 回答
5

@Bas 的答案是您可能正在寻找的答案。但这是另一种方法,使用 numpy 的vectorize技巧:

import numpy as np
S = set([0,2,6,8])

@np.vectorize
def contained(x):
    return x in S

contained(fake)
=> array([[ True, False,  True],
          [False, False, False],
          [ True, False,  True]], dtype=bool)

该解决方案的缺点contained()是为每个元素调用(即在 python 空间中),这比纯 numpy 解决方案慢得多。

于 2013-10-23T18:41:34.323 回答