簡體   English   中英

如何有效地獲取唯一值的索引列表?

[英]How to get lists of indices to unique values efficiently?

是否有一個內置的方法可以幫助我有效地實現以下目標:給定一個數組,我需要一個數組列表,每個數組都有索引到數組的不同唯一值?

如果f是所需的函數,

b = f(a)

u, idxs = unique(a)

然后

b[i] == where(idxs==i)[0]

我知道pandas.Series.groupby()可以做到這一點,但是當有超過10 ^ 5個唯一整數時創建一個dict可能效率不高。

如果你有numpy> = 1.9你可以這樣做:

>>> a = np.random.randint(5, size=10)
>>> a
array([0, 2, 4, 4, 2, 4, 4, 3, 2, 1])
>>> unq, unq_inv, unq_cnt = np.unique(a, return_inverse=True, return_counts=True)
>>> np.split(np.argsort(unq_inv), np.cumsum(unq_cnt[:-1]))
[array([0]), array([9]), array([1, 4, 8]), array([7]), array([2, 3, 5, 6])]
>>> unq
array([0, 1, 2, 3, 4])

在早期版本中,您可以獲得額外的計數:

>>> unq_cnt = np.bincount(unq_inv)

此外,如果您想確保每個值的索引都已排序,我認為您需要使用穩定的排序,例如np.argsort(unq_inv, kind='mergesort')


考慮到你的目標,我認為最大限度地減少對昂貴功能的要求,我認為你不需要做你想要的。 假設你的功能是平方的,你可以簡單地做:

>>> unq, unq_inv = np.unique(a, return_inverse=True)
>>> f_unq = unq**2
>>> f_a = f_unq[unq_inv]
>>> a
array([0, 2, 4, 4, 2, 4, 4, 3, 2, 1])
>>> f_a
array([ 0,  4, 16, 16,  4, 16, 16,  9,  4,  1])
def foo(a):
  I=np.arange(a.shape[0])
  d={}
  while a.shape[0]:
    x = a[0]
    ii = a==x
    d[x] = I[ii]
    a = a[~ii]
    I = I[~ii]
  return d

In [767]: a
Out[767]: array([4, 4, 3, 0, 0, 2, 1, 1, 0, 3])

In [768]: foo(a)
Out[768]: 
{0: array([3, 4, 8]),
 1: array([6, 7]),
 2: array([5]),
 3: array([2, 9]),
 4: array([0, 1])}

這是你想要的字典嗎?

對於小a這工作正常。

等效的字典構建功能是:

def foo1(a):
    unq = np.unique(a)
    return {i:np.where(a==i)[0] for i in unq}

我不知道unq_inv如何幫助構建字典。

foofoo1慢約30%。 我希望通過每次計算一個值來減少搜索到的數組,我可能會獲得一些速度。 但看起來額外的簿記會縮短時間。 where的時間可能不是的長度敏感的a

對於a2=np.random.randint(5000,size=100000)運行時間大約為2-3秒。

但是np.random.randint(50000,size=1000000)花費的時間太長(對於任一版本)。


在進一步的實驗中,使用collections.defaultdict的“啞”方法要快得多(20x):

def food(a):
    d = defaultdict(list)
    for i,j in enumerate(a):
        d[j].append(i)
    return d

“太大”(1000000)陣列僅需1.1秒;

也許做類似的事情:

s = argsort(a)
d = diff(a[s])
starts = where(d)[0]
f = [s[starts[i:i+1]] for i in xrange(len(a))]

(未檢查代碼)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM