Python 查找NumPy数组与值列表中的任何值相等的位置

Python 查找NumPy数组与值列表中的任何值相等的位置,python,arrays,numpy,Python,Arrays,Numpy,我有一个整数数组,希望找到该数组在哪里等于多个值列表中的任何值 通过单独处理每个值,或者在循环中使用多个“或”语句,可以很容易地做到这一点,但我觉得必须有更好/更快的方法来做到这一点。我实际上是在处理大小为4000 x 2000的数组,但下面是问题的简化版本: fake = arange(9).reshape((3,3)) array([[0, 1, 2], [3, 4, 5], [6, 7, 8]]) want = (fake==0) + (fake==2) +

我有一个整数数组,希望找到该数组在哪里等于多个值列表中的任何值

通过单独处理每个值,或者在循环中使用多个“或”语句,可以很容易地做到这一点,但我觉得必须有更好/更快的方法来做到这一点。我实际上是在处理大小为
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编写一个带有循环的函数要快得多。

该函数似乎可以实现您想要的功能。唯一的问题是它只适用于1d阵列,因此您应该像这样使用它:

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)

我不知道为什么这只限于1d阵列。从它的角度看,它首先似乎是将两个数组展平,然后再执行一些巧妙的排序技巧。但没有什么能阻止它在最后再次取消结果,就像我在这里不得不手工做的那样。

@Bas的答案可能就是你想要的答案。但这里有另一种方法,使用numpy的
矢量化
技巧:

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)
此解决方案的缺点是为每个元素(即在python空间中)调用
contained()
,这使得此解决方案比纯numpy解决方案慢得多。

numpy 0.13+ 从NumPy v0.13开始,您可以使用,它适用于多维阵列:

>>> 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]])
努比0.13之前
使用
np.in1d
的公认答案仅适用于1d数组,并且需要重新整形以获得所需的结果。这对于v0.13之前的NumPy版本很好。

Hmm。我编写了一个非常简单的函数来完成这项工作:
def EqualsAny(ar,vals):out=0(ar.shape,dtype=bool)对于vals中的val:out+=(ar==val)return out
我认为
NumPy.inad
会更快,但是它实际上需要更长的时间(对于相同的结果):
在[11]:%timeit EqualsAny(badlabels,smallnum)1个循环,在[7]:%timeit in1d(badlabels,smallnum)。重塑(badlabels.shape)1个循环,每个循环最好3:871 ms
不应该
numpy.in1d
因为它是用C写的,所以速度要快得多吗?我没有正确地使用
%timeit
吗?不,
in1d
不是用c编写的,而是用python编写的,请参阅我提供的源代码链接。它使用了各种numpy函数,如
排序
,希望能用C编写。它甚至有一些优化算法,用于
VAL
较短的情况,这与您的解决方案非常相似(但使用
|=
代替
+=
)。我不知道为什么您的版本更快,这可能取决于两个输入的长度。