2013-03-26 125 views

回答

33

unique()是緩慢的,O(n日誌(N)),但您可以通過下面的代碼做到這一點:

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)] 

輸出:

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

Pandas.unique()是快得多大陣列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

「O(N)」複雜性在任何地方都沒有提及,因此只是一個實現細節。該文檔簡單地表明它比'numpy.unique' *快得多,但這可能僅僅意味着它具有較小的常量或複雜度可能介於線性和NlogN之間。 – Bakuriu 2013-03-26 17:57:39

+3

它在這裏提到:http://www.slideshare.net/fullscreen/wesm/a-look-at-pandas-design-and-development/41 – HYRY 2013-03-26 22:40:26

+0

你將如何保留與'pandas.unique()'的順序?據我可以告訴它不允許任何參數。 – 2016-11-23 17:02:33

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

這僅僅是一個接受的答案的較慢版本 – Eric 2017-02-16 14:30:19

14

使用的np.uniquereturn_index功能。這將返回元素首次出現在輸入中的索引。然後argsort那些指數。

>>> 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

如果你想刪除的已排序可迭代重複,您可以使用itertools.groupby功能:

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

這更象UNIX「uniq的」命令,因爲它假設列表已經排序。當你嘗試無序列表中你會得到這樣的事情:

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

幾乎所有'numpy'問題都可以通過'numpy'解決得更快,純粹的Python解決方案將會很慢,因爲'numpy'是專業化的。 – jamylak 2013-03-26 13:09:15

1

如果要刪除重複項,像Unix工具uniq,這是一個解決方案:

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

這隻適用於數字。使用'!='而不是'-' – Eric 2017-02-16 14:31:22