Skip to main content
 首页 » 编程设计

python之Pandas:根据某些条件过滤 groupby 数据

2025年05月04日22artech

我正在尝试过滤掉以下代码中的数据子集。

如果该组中只有一个元素,我想用 FG='Y' 过滤那些列。此外,在 FG 列中同时具有“N”和“Y”组合的那些组中,当且仅当在 FG='N' 的 60 天后提交 FG='Y' 时,我才会选择它。

from datetime import timedelta 
import datetime as dt 
from dateutil.parser import parse 
import pandas as pd 
import numpy as np 
data={'Name':['A','A','A','B','B','B','C','D','D','D','E','E','E','F','G','G','G','H','H','H'],'FG':['Y','Y','Y','N','N','Y','Y','Y','Y','Y','Y','N','N','N','Y','N','N','Y','Y','N'], 
    'Program': ['Eval','Eval','Eval','IB','Eval','IB','PO','PO','Info','IB','Info','Info','Info','Ted', 'Info','Ted','Ted','PO','PO','PO'], 
    'Date':['2016/10/01','2017/10/01','2016/11/11','2017/10/01','2016/10/01','2017/10/02','2017/10/01','2017/10/01','2017/06/03', 
            '2017/10/01','2017/10/21','2017/10/21','2017/08/01','2017/10/10', '2017/10/21','2017/08/01','2017/10/10', '2017/04/01','2017/01/30','2017/01/01']} 
df=pd.DataFrame(data=data,columns=['Name','FG','Program', 'Date']) 
df['Date']=pd.to_datetime(df['Date']).dt.date 
df=df.sort_values('Date', ascending=True).drop_duplicates(subset=['Name', 'FG','Program'], keep='last') 
 
df['check']=df.groupby(['Name', 'Program']).Date.transform('min') 
df['check']=df['check']+timedelta(60) 
 
mask=df.groupby(['Name','Program']).apply(lambda x : ((x.FG=='Y') & (x.Date>= x.check)) if len(x.Date)>1 else x.FG=='Y')).values 
 
X=df[mask] 

预期的输出应该是

Name  FG  Program  Date 
A     Y   Eval     2017-10-01 
C     Y   PO       2017-10-01 
D     Y   Info     2017-06-03 
D     Y   PO       2017-10-01 
D     Y   IB       2017-10-01 
G     Y   Info     2017-10-21 
H     Y   PO       2017-04-01 

看来我在 mask 变量中的过滤器不起作用。此外,非常感谢任何将 FG='N' 的日期与 FG='Y' 的日期进行比较的建议

请您参考如下方法:

通过使用np.where

mask=df.groupby(['Name','Program']).\ 
       apply(lambda x : np.where(len(x.Date)>1,(x.FG=='Y') & (x.Date>= x.check),x.FG=='Y')).\ 
             apply(pd.Series).stack().values 
 
 
df.sort_values(['Name','Program']).loc[mask] 
Out[827]:  
   Name FG Program        Date       check 
1     A  Y    Eval  2017-10-01  2017-11-30 
6     C  Y      PO  2017-10-01  2017-11-30 
9     D  Y      IB  2017-10-01  2017-11-30 
8     D  Y    Info  2017-06-03  2017-08-02 
7     D  Y      PO  2017-10-01  2017-11-30 
14    G  Y    Info  2017-10-21  2017-12-20 
17    H  Y      PO  2017-04-01  2017-03-02