我有一个非常大的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
....
我想检查数组的第一列中是否存在一个值。我有很多本地方法(例如遍历每一行并进行检查),但是鉴于数组的大小,我想找到最有效的方法。
谢谢!
Answers:
怎么样
if value in my_array[:, col_num]:
do_whatever
编辑:我认为__contains__
以与@detly版本相同的方式实现
numpy
的any()
功能,我完全忘记了old in
。
value in …
比快any(… == value)
,因为它可以遍历数组元素并在遇到值时停止(与计算每个数组元素是否等于该值,然后检查布尔结果之一是否为真相反)。 。
any
是短路,不是numpy
吗?
对我来说最明显的是:
np.any(my_array[:, 0] == value)
my_array[:, 0]
为您提供了所有行(由表示:
),并且每行都有0
th元素,即第一列。例如,这是一个简单的一维数组[1, 3, 6, 2, 9]
。如果==
在带标量的numpy中使用运算符,它将进行逐元素比较,并返回与该数组相同形状的布尔numpy数组。所以[1, 3, 6, 2, 9] == 3
给[False, True, False, False, False]
。最后,np.any
检查此数组中的任何值是否为True
。
要检查多个值,可以使用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
numpy.in1d()
,代表速度非常快searchsorted()
。
IndexError
如果的任何元素values
大于的最大值,最后一行将抛出data
,因此需要特别注意。
index
为index % len(data)
或np.append(index[:-1],0)
等效。
迷人。我需要提高必须以相同方式执行匹配索引确定的一系列循环的速度。因此,我决定在此处安排所有解决方案的时间以及一些即兴演奏。
这是我对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
非常令人惊讶!数量级差!
总而言之,如果您只想知道某物是否在一维列表中:
如果您也想知道列表中的某处(顺序很重要):
对于numpy,将@HYRY的答案添加到in1d似乎是最快的。这是使用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
set
。OP以NumPy数组开头。