[英]Select all rows with 2 most recent dates by ID
我想按每个 ID 选择具有 2 个最近日期的所有行。 每个 ID 的 Max 和 Max-1 日期和行数可能因 ID 而异。
示例数据:
data = {'id': np.repeat((['a','b','c']), 6),
'date': ['2020-12-07', '2020-12-07','2020-12-05','2020-12-05','2020-12-04','2020-12-04',
'2021-12-07', '2021-12-07','2021-09-05','2021-09-05','2021-05-04','2021-05-04',
'2021-09-05', '2021-09-05','2021-02-05','2021-02-05','2020-12-04','2020-12-04'],
'value1': np.repeat(([10,20,30]), 6),
'value2': np.repeat(([1000,2000,3000]), 6)
}
df = pd.DataFrame(data)
期望的输出:
id date value1 value2
0 a 2020-12-07 10 1000
1 a 2020-12-07 10 1000
2 a 2020-12-05 10 1000
3 a 2020-12-05 10 1000
4 b 2021-12-07 20 2000
5 b 2021-12-07 20 2000
6 b 2021-09-05 20 2000
7 b 2021-09-05 20 2000
8 c 2021-09-05 30 3000
9 c 2021-09-05 30 3000
10 c 2021-02-05 30 3000
11 c 2021-02-05 30 3000
我读过.nlargest()
可以拉出最后两个日期,但是我很难找到将它应用于我的用例并在我的 df 中维护其他值的方法。
您可以尝试groupby().nth
:
df[df['date']>=df.groupby("id")["date"].transform('nth', n=2)]
输出:
id date value1 value2
0 a 2020-12-07 10 1000
1 a 2020-12-07 10 1000
2 a 2020-12-05 10 1000
3 a 2020-12-05 10 1000
6 b 2021-12-07 20 2000
7 b 2021-12-07 20 2000
8 b 2021-09-05 20 2000
9 b 2021-09-05 20 2000
12 c 2021-09-05 30 3000
13 c 2021-09-05 30 3000
14 c 2021-02-05 30 3000
15 c 2021-02-05 30 3000
您可以尝试使用“密集”排名:
>>> df[df.groupby("id")["date"].transform(pd.Series.rank, ascending=False, method="dense")<=2]
id date value1 value2
0 a 2020-12-07 10 1000
1 a 2020-12-07 10 1000
2 a 2020-12-05 10 1000
3 a 2020-12-05 10 1000
6 b 2021-12-07 20 2000
7 b 2021-12-07 20 2000
8 b 2021-09-05 20 2000
9 b 2021-09-05 20 2000
12 c 2021-09-05 30 3000
13 c 2021-09-05 30 3000
14 c 2021-02-05 30 3000
15 c 2021-02-05 30 3000
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.