Найти индексы большого массива, если он содержит значения в меньшем массиве

Есть ли функция быстрого numpy для возврата списка индексов в более крупном массиве, где он соответствует значениям из меньшего массива? Меньший массив равен ~ 30M, а размер больше 800M, поэтому я хочу избежать цикла для вызовов numpy.where .

Проблема с searchsorted заключается в том, что она вернет результаты, даже если их не является точным совпадением, он просто дает самый близкий индекс, но мне нужны только индексы, где есть точные совпадения

вместо этого:

 >>> a = array([1,2,3,4,5]) >>> b = array([2,4,7]) >>> searchsorted(a,b) array([1, 3, 5]) 

Я бы хотел:

 >>> a = array([1,2,3,4,5]) >>> b = array([2,4,7]) >>> SOMEFUNCTION(a,b) array([1, 3]) 

EDIT: набор значений как в малогабаритных, так и больших массивах всегда уникален и сортируется.

2 Solutions collect form web for “Найти индексы большого массива, если он содержит значения в меньшем массиве”

Вы можете использовать np.in1d чтобы найти те элементы a которые находятся в b . Чтобы найти индекс, используйте один вызов np.where :

 In [34]: a = array([1,2,3,4,5]) In [35]: b = array([2,4,7]) In [36]: np.in1d(a, b) Out[38]: array([False, True, False, True, False], dtype=bool) In [39]: np.where(np.in1d(a, b)) Out[39]: (array([1, 3]),) 

Поскольку a и b уже отсортированы, вы можете использовать

 In [57]: np.searchsorted(b, a, side='right') != np.searchsorted(b, a, side='left') Out[57]: array([False, True, False, True, False], dtype=bool) 

вместо np.in1d(a, b) . Для больших a и b использование searchsorted может быть быстрее:

 import numpy as np a = np.random.choice(10**7, size=10**6, replace=False) a.sort() b = np.random.choice(10**7, size=10**5, replace=False) b.sort() In [53]: %timeit np.in1d(a, b) 10 loops, best of 3: 176 ms per loop In [54]: %timeit np.searchsorted(b, a, side='right') != np.searchsorted(b, a, side='left') 10 loops, best of 3: 106 ms per loop 

Хайме и Дивакар предложили некоторые существенные улучшения в отношении метода, показанного выше. Вот какой код, который проверяет, что все методы возвращают один и тот же результат, а затем некоторые контрольные показатели:

 import numpy as np a = np.random.choice(10**7, size=10**6, replace=False) a.sort() b = np.random.choice(10**7, size=10**5, replace=False) b.sort() def using_searchsorted(a, b): return (np.where(np.searchsorted(b, a, side='right') != np.searchsorted(b, a, side='left')))[0] def using_in1d(a, b): return np.where(np.in1d(a, b))[0] def using_searchsorted_divakar(a, b): idx1 = np.searchsorted(a,b,'left') idx2 = np.searchsorted(a,b,'right') out = idx1[idx1 != idx2] return out def using_jaime_mask(haystack, needle): idx = np.searchsorted(haystack, needle) mask = idx < haystack.size mask[mask] = haystack[idx[mask]] == needle[mask] idx = idx[mask] return idx expected = using_searchsorted(a, b) for func in (using_in1d, using_searchsorted_divakar, using_jaime_mask): result = func(a, b) assert np.allclose(expected, result) 

 In [29]: %timeit using_jaime_mask(a, b) 100 loops, best of 3: 13 ms per loop In [28]: %timeit using_searchsorted_divakar(a, b) 10 loops, best of 3: 21.7 ms per loop In [26]: %timeit using_searchsorted(a, b) 10 loops, best of 3: 109 ms per loop In [27]: %timeit using_in1d(a, b) 10 loops, best of 3: 173 ms per loop 

По умолчанию направление np.searchsorted с np.searchsorted left . Мы также можем искать его в right направлении, а те, которые одинаковы в обоих наборах индексов, будут теми, которых следует избегать из индексов, выводимых из left опции, чтобы получить желаемый результат. Мотивация здесь та же, что и в @unutbu's solution .

Таким образом, реализация будет выглядеть так:

 idx1 = np.searchsorted(a,b,'left') idx2 = np.searchsorted(a,b,'right') out = idx1[idx1 != idx2] 
  • fminunc чередуется в numpy
  • Вычисление коэффициента корреляции между двумя многомерными массивами
  • Как обнаружить изменение знака для элементов в массиве numpy
  • Nump array integer / float division
  • Как нарезать numpy.ndarray, состоящий из numpy.void номеров?
  • проблемы с numpy genfromtxt в Python3
  • объединение 2D-массивов в 3D-массивы
  • Отображение данных из двоичного файла в python
  • Python - лучший язык программирования в мире.