Поиск уникальных точек в массиве numpy
Что такое более быстрый способ поиска уникальных точек x, y (удаление дубликатов) в массиве numpy, например:
points = numpy.random.randint(0, 5, (10,2))
Я думал о преобразовании точек в комплексные числа, а затем для проверки уникальности, но это кажется довольно запутанным:
b = numpy.unique(points[:,0] + 1j * points[:,1])
points = numpy.column_stack((b.real, b.imag))
Ответы
Ответ 1
Я бы сделал это следующим образом:
numpy.array(list(set(tuple(p) for p in points)))
Для быстрого решения в самом общем случае, может быть, этот рецепт вас будет интересовать:
http://code.activestate.com/recipes/52560-remove-duplicates-from-a-sequence/
Ответ 2
Думаю, у вас здесь очень хорошая идея. Подумайте о базовом блоке памяти, используемом для представления данных в points
. Мы говорим numpy о том, что этот блок представляет собой массив формы (10,2) с dtype int32
(32-разрядные целые числа), но почти бесценно сказать numpy рассматривать тот же блок памяти, что и массив массивов (10) с dtype c8
(64-битный комплекс).
Итак, единственная реальная стоимость - это вызов np.unique
, за которым следует еще один практически бесполезный вызов view
и reshape
:
import numpy as np
np.random.seed(1)
points = np.random.randint(0, 5, (10,2))
print(points)
print(len(points))
дает
[[3 4]
[0 1]
[3 0]
[0 1]
[4 4]
[1 2]
[4 2]
[4 3]
[4 2]
[4 2]]
10
а
cpoints = points.view('c8')
cpoints = np.unique(cpoints)
points = cpoints.view('i4').reshape((-1,2))
print(points)
print(len(points))
дает
[[0 1]
[1 2]
[3 0]
[3 4]
[4 2]
[4 3]
[4 4]]
7
Если вам не нужен результат для сортировки, метод wim будет быстрее (вы можете подумать о принятии его ответа...)
import numpy as np
np.random.seed(1)
N=10000
points = np.random.randint(0, 5, (N,2))
def using_unique():
cpoints = points.view('c8')
cpoints = np.unique(cpoints)
return cpoints.view('i4').reshape((-1,2))
def using_set():
return np.vstack([np.array(u) for u in set([tuple(p) for p in points])])
дает следующие этапы:
% python -mtimeit -s'import test' 'test.using_set()'
100 loops, best of 3: 18.3 msec per loop
% python -mtimeit -s'import test' 'test.using_unique()'
10 loops, best of 3: 40.6 msec per loop