2017-06-13 92 views
3

在熊貓我有以下形式的數據幀:熊貓:選擇行鍼對groupby.sum()滿足條件

>>> import pandas as pd 
>>> df = pd.DataFrame({'ID':[51,51,51,24,24,24,31], 'x':[0,1,0,0,1,1,0]}) 
>>> df 

ID x 
51 0 
51 1 
51 0 
24 0 
24 1 
24 1 
31 0 

對於每一個「ID」的「X」被記錄幾倍的值,它是0或1.我想從df中選擇那些包含'ID'的'ID'至少兩次的行。

對於每一個「ID」我設法count次「X」的個數爲1,由

>>> df.groupby('ID')['x'].sum() 

ID 
51 1 
24 2 
31 0 

但我不知道如何從這裏着手。我想下面的輸出:

ID x 
24 0 
24 1 
24 1 
+0

使用由濾波器組,以獲得ID,然後用結果來查詢你的主要table.I上午不是熊貓專家,所以對語法不太確定。 –

回答

4

使用groupbyfilter

df.groupby('ID').filter(lambda s: s.x.sum()>=2) 

輸出:

ID x 
3 24 0 
4 24 1 
5 24 1 
1
df = pd.DataFrame({'ID':[51,51,51,24,24,24,31], 'x':[0,1,0,0,1,1,0]}) 
df.loc[df.groupby(['ID'])['x'].transform(func=sum)>=2,:] 
out: 
    ID x 
3 24 0 
4 24 1 
5 24 1 
+0

你不需要第二個索引器,並使用''sum'''df.loc [df.groupby(['ID'])['x']。transform('sum')> = 2]' – piRSquared

+0

@ piRSquared謝謝〜你的回答也幫助我學到了很多〜 – Wen

+0

我很高興。希望能看到更多你的答案。 – piRSquared

1

使用np.bincountpd.factorize
替代進階ANCE技術,畫出更好的性能

f, u = df.ID.factorize() 
df[np.bincount(f, df.x.values)[f] >= 2] 

    ID x 
3 24 0 
4 24 1 
5 24 1 

在厭惡one-liner形式

df[(lambda f, w: np.bincount(f, w)[f] >= 2)(df.ID.factorize()[0], df.x.values)] 

    ID x 
3 24 0 
4 24 1 
5 24 1 

np.bincountnp.unique
我本可以用np.uniquereturn_inverse參數來完成日同樣的事情。但是,np.unique將對數組進行排序並將改變解決方案的時間複雜度。

u, f = np.unique(df.ID.values, return_inverse=True) 
df[np.bincount(f, df.x.values)[f] >= 2] 

一襯墊

df[(lambda f, w: np.bincount(f, w)[f] >= 2)(np.unique(df.ID.values, return_inverse=True)[1], df.x.values)] 

時序

%timeit df[(lambda f, w: np.bincount(f, w)[f] >= 2)(df.ID.factorize()[0], df.x.values)] 
%timeit df[(lambda f, w: np.bincount(f, w)[f] >= 2)(np.unique(df.ID.values, return_inverse=True)[1], df.x.values)] 
%timeit df.groupby('ID').filter(lambda s: s.x.sum()>=2) 
%timeit df.loc[df.groupby(['ID'])['x'].transform(func=sum)>=2] 
%timeit df.loc[df.groupby(['ID'])['x'].transform('sum')>=2] 

小數據

1000 loops, best of 3: 302 µs per loop 
1000 loops, best of 3: 241 µs per loop 
1000 loops, best of 3: 1.52 ms per loop 
1000 loops, best of 3: 1.2 ms per loop 
1000 loops, best of 3: 1.21 ms per loop 

大數據

np.random.seed([3,1415]) 
df = pd.DataFrame(dict(
     ID=np.random.randint(100, size=10000), 
     x=np.random.randint(2, size=10000) 
    )) 

1000 loops, best of 3: 528 µs per loop 
1000 loops, best of 3: 847 µs per loop 
10 loops, best of 3: 20.9 ms per loop 
1000 loops, best of 3: 1.47 ms per loop 
1000 loops, best of 3: 1.55 ms per loop 

更大的數據

np.random.seed([3,1415]) 
df = pd.DataFrame(dict(
     ID=np.random.randint(100, size=100000), 
     x=np.random.randint(2, size=100000) 
    )) 

1000 loops, best of 3: 2.01 ms per loop 
100 loops, best of 3: 6.44 ms per loop 
10 loops, best of 3: 29.4 ms per loop 
100 loops, best of 3: 3.84 ms per loop 
100 loops, best of 3: 3.74 ms per loop