簡體   English   中英

使用具有特定值的CountBy過濾Pandas DataFrame

[英]Filter Pandas DataFrame using GroupBy with Count of Certain Value

我想將pandas DataFrame過濾到特定行的組具有特定列值的最小計數的行。

例如,僅返回df的行/組,其中['c2','c3']組至少有2行且'c1'值為1:

df = pd.DataFrame({'c1':[0,1,0,1,1,0], 'c2':[0,0,0,1,1,1], 'c3':[0,0,0,1,1,1]})

結果應僅返回索引為3,4,5的行,因為只有[c2,c3] = [1,1]組至少有2行且'c1'值為1。

df.groupby(['c2','c3']).filter(lambda x: x['c1'].count() >= 2)

不返回所需的結果。 我需要計數專門應用於1的計數,而不僅僅是'c1'的任何值。

以下工作,但我不知道如何使它更pythonic:

s = df.groupby(['c2','c3']).apply(lambda x: x[x['c1']==1].count() >= 2).all(axis=1)
df = df.reset_index().set_index(['c2','c3']).loc[s[s].index].reset_index().set_index(['index'])    

使用groupby + transform對布爾系列求和,我們用它來掩蓋原始的DataFrame。

m = df['c1'].eq(1).groupby([df['c2'], df['c3']]).transform('sum').ge(2)

# Alterntively assign the column
#m = df.assign(to_sum = df.c1.eq(1)).groupby(['c2', 'c3']).to_sum.transform('sum').ge(2) 

df.loc[m]
#   c1  c2  c3
#3   1   1   1
#4   1   1   1
#5   0   1   1

使用過濾器, count不是正確的邏輯。 使用== (或.eq() )來檢查'c1'在哪里等於特定值。 對布爾系列求和並檢查濾波器每組至少有2次這樣的出現。

df.groupby(['c2','c3']).filter(lambda x: x['c1'].eq(1).sum() >= 2)
#   c1  c2  c3
#3   1   1   1
#4   1   1   1
#5   0   1   1

雖然對於小型DataFrame而言並不明顯,但隨着組數量的增加,使用lambda filter速度非常慢。 transform很快:

import numpy as np
np.random.seed(123)
df = pd.DataFrame({'c1':np.random.randint(1,100,1000), 'c2':np.random.randint(1,100,1000), 
                   'c3':np.random.choice([1,0], 1000)})

%%timeit
m = df['c1'].eq(1).groupby([df.c3, df.c3]).transform('sum').ge(2)
df.loc[m]
#5.21 ms ± 15.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

%timeit df.groupby(['c2','c3']).filter(lambda x: x['c1'].eq(1).sum() >= 2)
#124 ms ± 714 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

可以使用groupby + merge

s=df.groupby(['c2','c3']).c1.sum().ge(2)
s[s].index.to_frame().reset_index(drop=True).merge(df,how='left')
   c2  c3  c1
0   1   1   1
1   1   1   1
2   1   1   0

暫無
暫無

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

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