![](/img/trans.png)
[英]What is most efficient way to access nodes of a tree stored in a NumPy array
[英]What is the most efficient way to check if a value exists in a NumPy array?
我有一个非常大的 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
....
我想检查数组的第一列中是否存在值。 我有很多本土方法(例如遍历每一行并检查),但考虑到数组的大小,我想找到最有效的方法。
谢谢!
怎么样
if value in my_array[:, col_num]:
do_whatever
编辑:我认为__contains__
的实现方式与@detly 的版本相同
对我来说最明显的是:
np.any(my_array[:, 0] == value)
To check multiple values, you can use numpy.in1d(), which is an element-wise function version of the python keyword in. If your data is sorted, you can use 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
迷人。 我需要提高必须以相同方式执行匹配索引确定的一系列循环的速度。 所以我决定在这里计算所有解决方案的时间,以及一些即兴演奏。
这是我对 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 是最快的,但是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
构造一个集合比调用 in1d慢,但是检查值是否存在要快一点:
s = set(range(0, 99999, 3))
%timeit 10 in s
10000000 loops, best of 3: 47 ns per loop
据我所知,最方便的方法是:
(Val in X[:, col_num])
其中 Val 是您要检查的值, X 是数组。 在您的示例中,假设您要检查值 8 是否存在于您的第三列中。 简单地写
(8 in X[:, 2])
如果第三列中有 8,这将返回 True,否则返回 False。
如果您正在寻找整数列表,您可以使用索引来完成这项工作。 这也适用于 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。
如果要检查列表a
是否在 numpy 数组b
中,请使用以下语法:
np.any(np.equal(a, b).all(axis=1))
考虑到 numpy 阵列的形状为n*2
,放置axis = 1
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.