Ответ 1
Как насчет
if value in my_array[:, col_num]:
do_whatever
Изменить: я думаю, что __contains__
реализовано таким образом, что это то же самое, что @detly version
У меня очень большой массив 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 version
Время соревнований! Наиболее очевидным для меня было бы:
np.any(my_array[:, 0] == value)
Чтобы проверить несколько значений, вы можете использовать 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
Захватывающий. Мне нужно было улучшить скорость серии циклов, которые должны выполнять соответствующее определение индекса таким же образом. Поэтому я решил найти все решения здесь, а также некоторые риффы.
Вот мои тесты скорости для 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 или нет:
Если вы хотите узнать, где что-то находится в списке (порядок важен):
Добавление в @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