检查NumPy数组中是否存在值的最有效方法是什么?

jgzswidk  于 12个月前  发布在  其他
关注(0)|答案(8)|浏览(118)

我有一个非常大的NumPy数组
我想检查数组的第一列中是否存在值。我有一堆土生土长的方法(例如。遍历每一行并进行检查),但考虑到数组的大小,我想找到最有效的方法。
谢谢你,谢谢

mxg2im7a

mxg2im7a1#

怎么样

if value in my_array[:, col_num]:
    do_whatever

编辑:我认为__contains__的实现方式与@detly的版本相同

kq0g1dla

kq0g1dla2#

对我来说最明显的是:

np.any(my_array[:, 0] == value)
6tdlim6h

6tdlim6h3#

要检查多个值,可以使用numpy.in1d(),这是python关键字in的逐元素函数版本。如果你的数据是排序的,你可以使用numpy.searchsorted():

import numpy as np
data = np.array([1,4,5,5,6,8,8,9])
values = [2,3,4,6,7]
print np.in1d(values, data)

index = np.searchsorted(data, values)
print data[index] == values
vxf3dgd4

vxf3dgd44#

迷人.我需要提高一系列循环的速度,这些循环必须以同样的方式执行匹配索引确定。所以我决定把所有的解决方案都放在这里,沿着一些即兴表演。
以下是我对Python 2.7.10的速度测试:

import timeit
timeit.timeit('N.any(N.in1d(sids, val))', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')

18.86137104034424

timeit.timeit('val in sids', setup = 'import numpy as N; val = 20010401020091; sids = [20010401010101+x for x in range(1000)]')

15.061666011810303

timeit.timeit('N.in1d(sids, val)', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')

11.613027095794678

timeit.timeit('N.any(val == sids)', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')

7.670552015304565

timeit.timeit('val in sids', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')

5.610057830810547

timeit.timeit('val == sids', setup = 'import numpy as N; val = 20010401020091; sids = N.array([20010401010101+x for x in range(1000)])')

1.6632978916168213

timeit.timeit('val in sids', setup = 'import numpy as N; val = 20010401020091; sids = set([20010401010101+x for x in range(1000)])')

0.0548710823059082

timeit.timeit('val in sids', setup = 'import numpy as N; val = 20010401020091; sids = dict(zip([20010401010101+x for x in range(1000)],[True,]*1000))')

0.054754018783569336
太令人惊讶了!数量级的差距!
总结一下,如果你只是想知道某个东西是否在1D列表中:

  • 19s N.any(N.in1d(numpy array))
  • 15 s x in(列表)
  • 8s N.any(x == numpy array)
  • 6s x in(numpy数组)
  • .1s x in(集合或字典)

如果你也想知道某个东西在列表中的位置(顺序很重要):

  • 12 s N.in1d(x,numpy数组)
  • 2s x ==(numpy数组)
8wigbo56

8wigbo565#

在1d中添加@HYRY的答案似乎是numpy最快的。这是使用numpy 1.8和python 2.7.6。
在这个测试中,in 1d是最快的,但是10 in a看起来更干净:

a = arange(0,99999,3)
%timeit 10 in a
%timeit in1d(a, 10)

10000 loops, best of 3: 150 µs per loop
10000 loops, best of 3: 61.9 µs per loop

构造一个集合比调用in 1d,但检查值是否存在要快一点:

s = set(range(0, 99999, 3))
%timeit 10 in s

10000000 loops, best of 3: 47 ns per loop
ncgqoxb0

ncgqoxb06#

我认为最方便的方法是:

(Val in X[:, col_num])

其中瓦尔是要检查的值,X是数组。在你的例子中,假设你想检查值8是否存在于第三列中。简单地写

(8 in X[:, 2])

如果第三列中有8,则返回True,否则返回False。

mm9b1k5b

mm9b1k5b7#

如果你正在寻找一个整数列表,你可以使用索引来完成这项工作。这也适用于nd-arrays,但似乎更慢。这样做可能会更好,不止一次。

def valuesInArray(values, array):
    values = np.asanyarray(values)
    array = np.asanyarray(array)
    assert array.dtype == np.int and values.dtype == np.int
    
    matches = np.zeros(array.max()+1, dtype=np.bool_)
    matches[values] = True
    
    res = matches[array]
    
    return np.any(res), res
    
    
array = np.random.randint(0, 1000, (10000,3))
values = np.array((1,6,23,543,222))

matched, matches = valuesInArray(values, array)

通过使用numba和njit,我可以得到大约x10的加速。

igetnqfo

igetnqfo8#

我建议使用np.isin
本指南建议使用此函数来屏蔽值,但您可以直接在这些掩码上调用anyall来检查成员资格。我建议按照上面的建议使用timeit检查速度。
不要 * 使用for循环,这首先就击败了使用numpy的想法。
请注意,我已经将其扩展到任意维数组,但您始终可以使用自己的a切片来查看列内部,等等。
您可以通过将数组放在第一位来检查列表中的任何成员是否在数组中,或者将数组放在第二位来检查它是否包含列表的所有成员。

import numpy
a = np.arange(9).reshape((3,3))
any_lookup = [2,6,10,10002,34543,45]
all_lookup = [2,3,4,5]
none_lookup = [-10,435344,-255,557755]

res_any = np.isin(a,any_lookup)
res_all = np.isin(a,all_lookup)
res_none = np.isin(a,none_lookup)

print(res_any)
print(res_all)
print(res_none)

print(res_any.any())
print(res_all.any())
print(res_none.any())

print(np.isin(any_lookup,a).all())
print(np.isin(all_lookup,a).all())

结果如下:

[[False False  True]
 [False False False]
 [ True False False]]
[[False False  True]
 [ True  True  True]
 [False False False]]
[[False False False]
 [False False False]
 [False False False]]
True
True
False
False
True

相关问题