2017-04-02 62 views
2

我期待使用numpy.unique來獲取pandas.DataFrame的兩列的反向唯一索引。在pandas.DataFrame的多列上使用numpy.unique

我知道如何使用它的一列:

u, rev = numpy.unique(df[col], return_inverse=True) 

但我想用它在多個列上。例如,如果df樣子:

0 1 
0 1 1 
1 1 2 
2 2 1 
3 2 1 
4 3 1 

話,我想獲得的反向指標:

[0,1,2,2,3] 

回答

2

方法#1

這裏有一個NumPy的方法各行各行的思維轉換成標量作爲一個索引元組在兩維(2列數據)網格 -

def unique_return_inverse_2D(a): # a is array 
    a1D = a.dot(np.append((a.max(0)+1)[:0:-1].cumprod()[::-1],1)) 
    return np.unique(a1D, return_inverse=1)[1] 

如果您有負數數據,我們也需要使用min來獲得這些標量。因此,在這種情況下,請使用a.max(0) - a.min(0) + 1代替a.max(0) + 1

方法2

這裏的重點是性能的另一個與NumPy的意見基礎的解決方案通過this smart solution by @Eric啓發 -

def unique_return_inverse_2D_viewbased(a): # a is array 
    a = np.ascontiguousarray(a) 
    void_dt = np.dtype((np.void, a.dtype.itemsize * np.prod(a.shape[1:]))) 
    return np.unique(a.view(void_dt).ravel(), return_inverse=1)[1] 

樣品試驗 -

In [209]: df 
Out[209]: 
    0 1 2 3 
0 21 7 31 69 
1 62 75 22 62 # ----| 
2 16 46 9 31 #  |==> Identical rows, so must have same IDs 
3 62 75 22 62 # ----| 
4 24 12 88 15 

In [210]: unique_return_inverse_2D(df.values) 
Out[210]: array([1, 3, 0, 3, 2]) 

In [211]: unique_return_inverse_2D_viewbased(df.values) 
Out[211]: array([1, 3, 0, 3, 2]) 
1

我覺得你可以列轉換爲strings然後sum

u, rev = np.unique(df.astype(str).values.sum(axis=1), return_inverse=True) 
print (rev) 
[0 1 2 2 3] 

如指出DSM(謝謝),這是危險的。

另一種解決方案是行轉換爲tuples

u, rev = np.unique(df.apply(tuple, axis=1), return_inverse=True) 
print (rev) 
[0 1 2 2 3] 
+3

危險。這將無法從1,12中清除第11,2行。 – DSM

+0

@DSM - 你說得對,所以我再添加一個sol。 – jezrael