首页 文章

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

提问于
浏览
39

我有一个非常大的NumPy数组

1 40 3
4 50 4
5 60 7
5 49 6
6 70 8
8 80 9
8 72 1
9 90 7
....

我想检查数组的第一列中是否存在值 . 我有一堆本土方式(例如遍历每一行并检查),但考虑到数组的大小,我想找到最有效的方法 .

谢谢!

7 回答

  • 30

    迷人 . 我需要提高一系列循环的速度,这些循环必须以同样的方式执行匹配的索引确定 . 所以我决定在这里解决所有的解决方案,以及一些riff .

    以下是我对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

    非常令人惊讶!数量级差异的订单!

    总而言之,如果您只是想知道某个列表中是否存在某些内容:

    • 19s N.any(N.in1d(numpy array))

    • 15s x in(列表)

    • 8s N.any(x == numpy数组)

    • 6s x in(numpy数组)

    • .1s x in(set或字典)

    如果你想知道列表中的某些内容(顺序很重要):

    • 12s N.in1d(x,numpy数组)

    • 2s x ==(numpy数组)

  • 1

    要检查多个值,可以使用numpy.in1d(),这是python关键字的元素功能版本 . 如果您的数据已排序,则可以使用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
    
  • -1

    根据我的最方便的方式是:

    (Val in X[:, col_num])
    

    其中Val是您要检查的值,X是数组 . 在您的示例中,假设您要检查第三列中是否存在值8 . 简单写一下

    (8 in X[:, 2])
    

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

  • 49

    添加到@ HYRY的答案in1d似乎是最快的numpy . 这是使用numpy 1.8和python 2.7.6 .

    在这个测试中,in1d最快:

    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
    

    使用Python集似乎是最快的:

    s = set(range(0, 99999, 3))
    %timeit 10 in s
    
    10000000 loops, best of 3: 47 ns per loop
    
  • 9

    如果要检查列表 a 是否在numpy数组 b 中,请使用以下语法:

    np.any(np.equal(a, b).all(axis=1))
    

    axis = 1 考虑为numpy数组的形状 n*2

  • 26

    对我来说最明显的是:

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

    怎么样

    if value in my_array[:, col_num]:
        do_whatever
    

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

相关问题