[То, что следует, фактически частично неверно (см. PS):]
Следующий способ получения уникальных элементов во всех подмассивах очень быстрый:
seq = itertools.chain(tab[indices1].flat, tab[indices2].flat, tab[indices3].flat, tab[indices4].flat)
result = set(seq)
Примечаниечто flat
(который возвращает итератор) используется вместо flatten()
(который возвращает полный массив), и что set()
можно вызывать напрямую (вместо использования map()
и словаря, как во втором методе)).
Вот результаты синхронизации (полученные в оболочке IPython):
>>> %timeit result = numpy.unique(numpy.array([tab[indices1], tab[indices2], tab[indices3], tab[indices4]]))
100 loops, best of 3: 8.04 ms per loop
>>> seq = itertools.chain(tab[indices1].flat, tab[indices2].flat, tab[indices3].flat, tab[indices4].flat)
>>> %timeit set(seq)
1000000 loops, best of 3: 223 ns per loop
Таким образом, метод set / flat в этом примере в 40 раз быстрее.
PS : время set(seq)
на самом деле не является репрезентативным.Фактически, первый цикл синхронизации очищает итератор seq
, а последующие оценки set()
возвращают пустой набор!Правильный временной тест - следующий
>>> %timeit set(itertools.chain(tab[indices1].flat, tab[indices2].flat, tab[indices3].flat, tab[indices4].flat))
100 loops, best of 3: 9.12 ms per loop
, который показывает, что метод set / flat на самом деле не быстрее.
PPS : здесь (неудачное) исследованиепредложения mtrw;поиск уникальных индексов заранее может быть хорошей идеей, но я не могу найти способ реализовать его, который быстрее, чем описанный выше подход:
>>> %timeit set(indices1).union(indices2).union(indices3).union(indices4)
100 loops, best of 3: 11.9 ms per loop
>>> %timeit set(itertools.chain(indices1.flat, indices2.flat, indices3.flat, indices4.flat))
100 loops, best of 3: 10.8 ms per loop
Таким образом, поиск набора всех различных индексов сам по себедовольно медленно.
PPPS : numpy.unique(<concatenated array of indices>)
на самом деле в 2-3 раза быстрее, чем set(<concatenated array of indices>)
.Это ключ к ускорению, полученному в ответе Баго (unique(concatenate((…)))
).Вероятно, причина в том, что позволить NumPy самостоятельно обрабатывать свои массивы, как правило, быстрее, чем связывать чистый Python (set
) с массивами NumPy.
Заключение : поэтому этот ответ только документирует неудачные попытки, которыене следует полностью следовать, а также, возможно, полезное замечание о временном коде с итераторами ...