![](/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.