2013-03-26 6 views

Antwort

33

unique() ist langsam, O (Nlog (N)), aber Sie können dies durch folgenden Code tun:

import numpy as np 
a = np.array(['b','a','b','b','d','a','a','c','c']) 
_, idx = np.unique(a, return_index=True) 
print a[np.sort(idx)] 

Ausgang:

['b' 'a' 'd' 'c'] 

Pandas.unique() ist viel schneller für große Array O (N):

import pandas as pd 

a = np.random.randint(0, 1000, 10000) 
%timeit np.unique(a) 
%timeit pd.unique(a) 

1000 loops, best of 3: 644 us per loop 
10000 loops, best of 3: 144 us per loop 
+0

Die O (N) -Komplexität wird nirgends erwähnt und ist daher nur ein Implementierungsdetail. Die Dokumentation besagt einfach, dass es * wesentlich schneller ist als "numpy.unique" *, aber dies kann einfach bedeuten, dass es kleinere Konstanten hat oder die Komplexität zwischen linear und NlogN liegt. – Bakuriu

+3

Es wird hier erwähnt: http://www.slideshare.net/fullscreen/wesm/a-look-at-pandas-design-and-development/41 – HYRY

+0

Wie würden Sie die Bestellung mit 'pandas.unique()' erhalten? Soweit ich das beurteilen kann, erlaubt es keine Parameter. –

7
a = ['b','b','b','a','a','c','c'] 
[a[i] for i in sorted(np.unique(a, return_index=True)[1])] 
+0

Dies ist nur ein langsamere Version der akzeptierten Antwort – Eric

14

Verwenden Sie die return_index Funktionalität von np.unique. Dies gibt die Indizes zurück, bei denen die Elemente in der Eingabe zum ersten Mal aufgetreten sind. Dann argsort diese Indizes.

>>> u, ind = np.unique(['b','b','b','a','a','c','c'], return_index=True) 
>>> u[np.argsort(ind)] 
array(['b', 'a', 'c'], 
     dtype='|S1') 
1

Wenn Sie versuchen, Duplikation eines bereits sortiert iterable zu entfernen, können Sie itertools.groupby Funktion:

>>> from itertools import groupby 
>>> a = ['b','b','b','a','a','c','c'] 
>>> [x[0] for x in groupby(a)] 
['b', 'a', 'c'] 

Dies funktioniert eher wie Unix ‚uniq‘ Befehl, weil es die Liste geht davon aus bereits sortiert. Wenn Sie es auf unsortierten Liste versuchen, werden Sie etwas wie diese:

>>> b = ['b','b','b','a','a','c','c','a','a'] 
>>> [x[0] for x in groupby(b)] 
['b', 'a', 'c', 'a'] 
+2

Nahezu die ganze Zeit werden 'numpy' Probleme mit' numpy' schneller gelöst, reine Python-Lösungen werden langsamer, da 'numpy' spezialisiert ist. – jamylak

1

Wenn Sie wiederholte Einträge löschen möchten, wie das Unix-Tool uniq, ist dies eine Lösung:

def uniq(seq): 
    """ 
    Like Unix tool uniq. Removes repeated entries. 
    :param seq: numpy.array 
    :return: seq 
    """ 
    diffs = np.ones_like(seq) 
    diffs[1:] = seq[1:] - seq[:-1] 
    idx = diffs.nonzero() 
    return seq[idx] 
+1

Dies funktioniert nur für Zahlen. Verwenden Sie '! =' Anstelle von '-' – Eric