根据熊猫数据框中的ID查找下一个非null值

时间:2020-03-24 09:49:38

标签: python pandas

我有以下数据框

date            id      type
11/10/2019      1       A
15/10/2019      1       B
05/11/2019      1       B
11/11/2019      1       A
15/10/2019      2       B
21/10/2019      2       A
31/10/2019      2       B
21/11/2019      2       A
21/12/2019      2       A
18/11/2019      3       A
21/11/2019      3       B
27/11/2019      3       B
14/12/2019      3       A

我想标记此数据框中满足以下条件的每一行

  • 类型为A

  • 在当前行的前/后正好1个月存在一个类型为A且具有相同ID的行

也就是说,我想将上述数据框转换为

date            id      type    flagged
11/10/2019      1       A       True
15/10/2019      1       B       False
05/11/2019      1       B       False
11/11/2019      1       A       True    
15/10/2019      2       B       False
21/10/2019      2       A       True
31/10/2019      2       B       False
21/11/2019      2       A       True
21/12/2019      2       A       True
18/11/2019      3       A       False
21/11/2019      3       B       False
27/11/2019      3       B       False
14/12/2019      3       A       False

问题:我该如何解决此问题?

1 个答案:

答案 0 :(得分:0)

这是我非常简单的方法

df['data'] = pd.to_datetime(df['data'], format = '%d/%m/%Y')
df['dt'] = list(zip(df['id'], df['type'], pd.to_datetime(df['data']).dt.date))
df['fwd'] = list(zip(df['id'], df['type'], (pd.to_datetime(df['data']) + pd.DateOffset(months=1)).dt.date))
df['bwd']= list(zip(df['id'], df['type'], (pd.to_datetime(df['data']) - pd.DateOffset(months=1)).dt.date))

Out[1]:
    data       id   type    dt                fwd                 bwd              
0   2019-10-11  1   A   (1, A, 2019-10-11)  (1, A, 2019-11-11)  (1, A, 2019-09-11)  
1   2019-10-15  1   B   (1, B, 2019-10-15)  (1, B, 2019-11-15)  (1, B, 2019-09-15)  
2   2019-11-05  1   B   (1, B, 2019-11-05)  (1, B, 2019-12-05)  (1, B, 2019-10-05)  
3   2019-11-11  1   A   (1, A, 2019-11-11)  (1, A, 2019-12-11)  (1, A, 2019-10-11)  
4   2019-10-15  2   B   (2, B, 2019-10-15)  (2, B, 2019-11-15)  (2, B, 2019-09-15)  
5   2019-10-21  2   A   (2, A, 2019-10-21)  (2, A, 2019-11-21)  (2, A, 2019-09-21)  
6   2019-10-31  2   B   (2, B, 2019-10-31)  (2, B, 2019-11-30)  (2, B, 2019-09-30)  
7   2019-11-21  2   A   (2, A, 2019-11-21)  (2, A, 2019-12-21)  (2, A, 2019-10-21)  
8   2019-12-21  2   A   (2, A, 2019-12-21)  (2, A, 2020-01-21)  (2, A, 2019-11-21)  
9   2019-11-18  3   A   (3, A, 2019-11-18)  (3, A, 2019-12-18)  (3, A, 2019-10-18)  
10  2019-11-21  3   B   (3, B, 2019-11-21)  (3, B, 2019-12-21)  (3, B, 2019-10-21)  
11  2019-11-27  3   B   (3, B, 2019-11-27)  (3, B, 2019-12-27)  (3, B, 2019-10-27)  
12  2019-12-14  3   A   (3, A, 2019-12-14)  (3, A, 2020-01-14)  (3, A, 2019-11-14)  


df['flagged'] = [(f[1] =='A') and ((f in list(df['fwd'])) or (f in list(df['bwd']))) for f in df['dt']]
df[['data','id','type','flagged']]


Out[2]:

    data       id   type flagged
0   2019-10-11  1   A   True
1   2019-10-15  1   B   False
2   2019-11-05  1   B   False
3   2019-11-11  1   A   True
4   2019-10-15  2   B   False
5   2019-10-21  2   A   True
6   2019-10-31  2   B   False
7   2019-11-21  2   A   True
8   2019-12-21  2   A   True
9   2019-11-18  3   A   False
10  2019-11-21  3   B   False
11  2019-11-27  3   B   False
12  2019-12-14  3   A   False