2014-02-19 109 views
2

我有重複列一個numpy的數組:獲取指標的numpy的陣列的重複列

import numpy as np 

A = np.array([[1, 1, 1, 0, 1, 1], 
       [1, 2, 2, 0, 1, 2], 
       [1, 3, 3, 0, 1, 3]]) 

我需要找到索引這些重複或類似的東西:

[0 ,4]

[1,2,5]

我也很難用Python處理索引。我真的不知道要接近它。

感謝

我試着用這個功能首先要識別唯一列:

def unique_columns(data): 
    ind = np.lexsort(data) 
    return data.T[ind[np.concatenate(([True], any(data.T[ind[1:]]!=data.T[ind[:-1]], axis=1)))]].T 

但我不能從那裏找出指標。

+0

你需要numpy的性能,還是純粹的python實現行嗎? – wim

+0

你近了,你已經找到了所有獨特的列。每個真值都是新組開始的位置。 'ind'擁有你想要的所有指數,但通過indexing ind你只需要一個值而不是全部。嘗試在連續Tru之間的'ind'中獲取所有值。 –

+0

謝謝你們。我認爲這樣做。我是Python新手;來自C++的老學校,我覺得在Python中處理索引是不自然的。我用numpy是因爲我的數組非常大[300000,1000] – user3329302

回答

2

不幸的是,沒有一種簡單的方法可以做到這一點。使用np.unique答案。此方法要求您要唯一的軸在內存中連續,numpy的典型內存佈局爲行中連續或連續的C。幸運的numpy的,使這種轉換很簡單:

A = np.array([[1, 1, 1, 0, 1, 1], 
       [1, 2, 2, 0, 1, 2], 
       [1, 3, 3, 0, 1, 3]]) 

def unique_columns2(data): 
    dt = np.dtype((np.void, data.dtype.itemsize * data.shape[0])) 
    dataf = np.asfortranarray(data).view(dt) 
    u,uind = np.unique(dataf, return_inverse=True) 
    u = u.view(data.dtype).reshape(-1,data.shape[0]).T 
    return (u,uind) 

我們的結果是:

u,uind = unique_columns2(A) 

u 
array([[0, 1, 1], 
     [0, 1, 2], 
     [0, 1, 3]]) 
uind 
array([1, 2, 2, 0, 1, 2]) 

我真的不知道你想從這裏做什麼,比如你可以這樣做:

>>> [np.where(uind==x)[0] for x in range(u.shape[0])] 
[array([3]), array([0, 4]), array([1, 2, 5])] 

一些計時:

tmp = np.random.randint(0,4,(30000,500)) 

#BiRico and OP's answer 
%timeit unique_columns(tmp) 
1 loops, best of 3: 2.91 s per loop 

%timeit unique_columns2(tmp) 
1 loops, best of 3: 208 ms per loop 
+0

有一種簡單的方法可以做到這一點。 –

+0

@BiRico然後請展示它,而不是給出模糊的提示。另外,我並沒有看到lexsort對於大量的行來說更快而「唯一」。 – Daniel

+0

如果您願意,可隨意實施,現在我沒有電腦可以寫出來測試它。 –

0

這裏是如何處理它的大綱。使用numpy.lexsort對列進行排序,這樣所有副本將被組合在一起。一旦所有副本都在一起,您就可以輕鬆地確定哪些列是重複項以及與這些列對應的索引。

下面是上述方法的實現。

import numpy as np 

def duplicate_columns(data, minoccur=2): 
    ind = np.lexsort(data) 
    diff = np.any(data.T[ind[1:]] != data.T[ind[:-1]], axis=1) 
    edges = np.where(diff)[0] + 1 
    result = np.split(ind, edges) 
    result = [group for group in result if len(group) >= minoccur] 
    return result 

A = np.array([[1, 1, 1, 0, 1, 1], 
       [1, 2, 2, 0, 1, 2], 
       [1, 3, 3, 0, 1, 3]]) 
print(duplicate_columns(A)) 
# [array([0, 4]), array([1, 2, 5])]