Pandas Groupby 之前的行日期条件过滤器 - MAXIFS/MINIFS

Pandas Row Date Conditional Filter Prior to Groupby - MAXIFS/MINIFS

我正尝试在 Pandas

中进行 MAXIFS 样式计算

我正在尝试添加一个包含每个唯一 ID 的下一个(如果存在)和最后一个(如果存在)标记日期的列

示例 Table:(尝试获取下一个标志和最后一个标志列)

编辑:为了形成一个更通用的案例,如果您想执行另一个函数怎么办,例如 ditinctcount over the period <= to the row

我们的想法是能够应用仅应用于过滤子集的自定义函数,其中每个 Id = 行 ID 且日期 <= 行日期 (我已经创建了 pandas 兼容的行函数,但它太慢了)

Table:

Id      Date        Flag    Next Flag   Last Flag   Flag2   UniqueFlags 
1       21-Aug      0       NaN         18-Aug              1
1       20-Aug      0       NaN         18-Aug              1
1       19-Aug      0       NaN         18-Aug              1
1       18-Aug      1       NaN         18-Aug      A       1
1       17-Aug      0       18-Aug      15-Aug              1
1       16-Aug      0       18-Aug      15-Aug              1
1       15-Aug      1       18-Aug      15-Aug      A       1
1       14-Aug      0       15-Aug      NaN                 0
1       13-Aug      0       15-Aug      NaN                 0
2       21-Aug      0       NaN         19-Aug              2
2       20-Aug      0       NaN         19-Aug              2
2       19-Aug      1       NaN         19-Aug      A       2
2       18-Aug      0       19-Aug      15-Aug              1
2       17-Aug      0       19-Aug      15-Aug              1
2       16-Aug      0       19-Aug      15-Aug              1
2       15-Aug      1       19-Aug      15-Aug      B       1
2       14-Aug      0       15-Aug      NaN                 0
2       13-Aug      0       15-Aug      NaN                 0
3       21-Aug      0       NaN         17-Aug              1
3       20-Aug      0       NaN         17-Aug              1
3       19-Aug      0       NaN         17-Aug              1
3       18-Aug      0       NaN         17-Aug              1
3       17-Aug      1       NaN         17-Aug      A       1
3       16-Aug      0       17-Aug      NaN                 0
3       15-Aug      0       17-Aug      NaN                 0
3       14-Aug      0       17-Aug      NaN                 0
3       13-Aug      0       17-Aug      NaN                 0

我试过 groupby 但不能让它只适用于日期 <= 到行日期,同时也适用于每个 ID

谢谢

试试这个?我分解了这些步骤,假设您已经 sort_values 按列 IdDate

df['Next Flag']=np.nan
df['Last Flag']=np.nan
df.loc[(df.Flag==1).shift().fillna(False),'Next Flag']=df.Date.shift()
df.loc[(df.Flag==1).fillna(False),'Last Flag']=df.Date
df[['Next Flag','Last Flag']]=df.groupby('Id').agg({'Next Flag':'ffill','Last Flag':'bfill'})


    Id    Date  Flag Next Flag Last Flag
0    1  21-Aug     0       NaN    18-Aug
1    1  20-Aug     0       NaN    18-Aug
2    1  19-Aug     0       NaN    18-Aug
3    1  18-Aug     1       NaN    18-Aug
4    1  17-Aug     0    18-Aug    15-Aug
5    1  16-Aug     0    18-Aug    15-Aug
6    1  15-Aug     1    18-Aug    15-Aug
7    1  14-Aug     0    15-Aug       NaN
8    1  13-Aug     0    15-Aug       NaN
9    2  21-Aug     0       NaN    19-Aug
10   2  20-Aug     0       NaN    19-Aug
11   2  19-Aug     1       NaN    19-Aug
12   2  18-Aug     0    19-Aug    15-Aug
13   2  17-Aug     0    19-Aug    15-Aug
14   2  16-Aug     0    19-Aug    15-Aug
15   2  15-Aug     1    19-Aug    15-Aug
16   2  14-Aug     0    15-Aug       NaN
17   2  13-Aug     0    15-Aug       NaN
18   3  21-Aug     0       NaN    17-Aug
19   3  20-Aug     0       NaN    17-Aug
20   3  19-Aug     0       NaN    17-Aug
21   3  18-Aug     0       NaN    17-Aug
22   3  17-Aug     1       NaN    17-Aug
23   3  16-Aug     0    17-Aug       NaN
24   3  15-Aug     0    17-Aug       NaN
25   3  14-Aug     0    17-Aug       NaN
26   3  13-Aug     0    17-Aug       NaN

编辑:根据您更新的问题

df=df.drop(['Next Flag','Last Flag','UniqueFlags'],axis=1)
df['Next Flag']=np.nan
df['Last Flag']=np.nan
df.loc[(df.Flag==1).shift().fillna(False),'Next Flag']=df.Date.shift()
df.loc[(df.Flag==1).fillna(False),'Last Flag']=df.Date
df.Flag2=df.Flag2.replace({'':np.nan})
df[['Next Flag','Last Flag','Flag3']]=df.groupby('Id').agg({'Next Flag':'ffill','Last Flag':'bfill','Flag2':'bfill'})
df=df.sort_values(['Id','Date'],ascending=[True,True])
df['LOL']=df1.Flag3!=df1.Flag3.shift()
df.loc[df.Flag3.isnull(),'LOL']=False
df['LOL']=df['LOL'].astype(int)
df['UniqueFlags']=df.groupby('Id').LOL.cumsum()
df=df.sort_values(['Id','Date'],ascending=[True,False]).drop(['Flag3','LOL'],axis=1)


df
Out[1665]: 
    Id    Date  Flag Flag2 Next Flag Last Flag  UniqueFlags
0    1  21-Aug     0   NaN       NaN    18-Aug            1
1    1  20-Aug     0   NaN       NaN    18-Aug            1
2    1  19-Aug     0   NaN       NaN    18-Aug            1
3    1  18-Aug     1     A       NaN    18-Aug            1
4    1  17-Aug     0   NaN    18-Aug    15-Aug            1
5    1  16-Aug     0   NaN    18-Aug    15-Aug            1
6    1  15-Aug     1     A    18-Aug    15-Aug            1
7    1  14-Aug     0   NaN    15-Aug       NaN            0
8    1  13-Aug     0   NaN    15-Aug       NaN            0
9    2  21-Aug     0   NaN       NaN    19-Aug            2
10   2  20-Aug     0   NaN       NaN    19-Aug            2
11   2  19-Aug     1     A       NaN    19-Aug            2
12   2  18-Aug     0   NaN    19-Aug    15-Aug            1
13   2  17-Aug     0   NaN    19-Aug    15-Aug            1
14   2  16-Aug     0   NaN    19-Aug    15-Aug            1
15   2  15-Aug     1     B    19-Aug    15-Aug            1
16   2  14-Aug     0   NaN    15-Aug       NaN            0
17   2  13-Aug     0   NaN    15-Aug       NaN            0
18   3  21-Aug     0   NaN       NaN    17-Aug            1
19   3  20-Aug     0   NaN       NaN    17-Aug            1
20   3  19-Aug     0   NaN       NaN    17-Aug            1
21   3  18-Aug     0   NaN       NaN    17-Aug            1
22   3  17-Aug     1     A       NaN    17-Aug            1
23   3  16-Aug     0   NaN    17-Aug       NaN            0
24   3  15-Aug     0   NaN    17-Aug       NaN            0
25   3  14-Aug     0   NaN    17-Aug       NaN            0
26   3  13-Aug     0   NaN    17-Aug       NaN            0