使用Groupby删除DataFrame中每个id的开始日期和结束日期不同的行



我有以下df,并希望为每个id删除offer_date之前和mature_date之后的行(date-d/m/y(。最后的df看起来像final df。任何关于这个groupby的帮助都会很棒!

df

date   offer_date mature_date  id    a    b    c   d
0    1/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
1    2/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
2    3/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
3    4/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
4    5/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
5    6/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
6    7/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
7    8/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
8    9/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
9    10/1/2000 4/1/2000   9/1/2000    1   10   20  10.0  11
10   1/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
11   2/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
12   3/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
13   4/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
14   5/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
15   6/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
16   7/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
17   8/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
18   9/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
19   10/1/2000 1/1/2000   5/1/2000    2   30   30  40.0  15
20   1/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
21   2/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
22   3/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
23   4/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
24   5/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
25   6/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
26   7/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
27   8/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
28   9/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
29   10/1/2000 2/1/2000   4/1/2000    3   33   35  40.0  15

最终df

date   offer_date mature_date  id    a    b    c   d
3    4/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
4    5/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
5    6/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
6    7/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
7    8/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
8    9/1/2000  4/1/2000   9/1/2000    1   10   20  10.0  11
10   1/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
11   2/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
12   3/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
13   4/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
14   5/1/2000  1/1/2000   5/1/2000    2   30   30  40.0  15
21   2/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
22   3/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15
23   4/1/2000  2/1/2000   4/1/2000    3   33   35  40.0  15

您实际上不需要groupby,您可以执行全局mask,因为所有日期都可以按行进行比较。转换to_datetime列以确保良好的比较。

# format for dates with day first
date_format = '%d/%m/%Y'
# create the mask with both inequality
# convert to dateitme to be ensure the selection
mask = (
pd.to_datetime(df['date'], format=date_format)
.ge(pd.to_datetime(df['offer_date'], format=date_format)) 
& pd.to_datetime(df['date'], format=date_format)
.le(pd.to_datetime(df['mature_date'], format=date_format))
)
print(df.loc[mask])
date offer_date mature_date  id   a   b     c   d
3   4/1/2000   4/1/2000    9/1/2000   1  10  20  10.0  11
4   5/1/2000   4/1/2000    9/1/2000   1  10  20  10.0  11
5   6/1/2000   4/1/2000    9/1/2000   1  10  20  10.0  11
6   7/1/2000   4/1/2000    9/1/2000   1  10  20  10.0  11
7   8/1/2000   4/1/2000    9/1/2000   1  10  20  10.0  11
8   9/1/2000   4/1/2000    9/1/2000   1  10  20  10.0  11
10  1/1/2000   1/1/2000    5/1/2000   2  30  30  40.0  15
11  2/1/2000   1/1/2000    5/1/2000   2  30  30  40.0  15
12  3/1/2000   1/1/2000    5/1/2000   2  30  30  40.0  15
13  4/1/2000   1/1/2000    5/1/2000   2  30  30  40.0  15
14  5/1/2000   1/1/2000    5/1/2000   2  30  30  40.0  15
21  2/1/2000   2/1/2000    4/1/2000   3  33  35  40.0  15
22  3/1/2000   2/1/2000    4/1/2000   3  33  35  40.0  15
23  4/1/2000   2/1/2000    4/1/2000   3  33  35  40.0  15

EDIT:正如@Henry Ecker所指出的,在这种情况下,对于简单的日期格式,可以使用参数dayfirst,因此对每个日期列使用该pd.to_datetime(df['date'], dayfirst=True)而不是定义格式也可以。

最新更新