如何在Pandas DataFrame中提取最近N个日期的全部行?
问题描述
我有如下结构的Pandas DataFrame:
| No | Date | hours | Flag | |:------|:-----------|:---------|:----------| | 101 | 13.01.2021 | 2:45 | 0 | | 101 | 13.01.2021 | 1:20 | 0 | | 101 | 15.02.2021 | 3:15 | 0 | | 101 | 16.02.2021 | 0:30 | 0 | | 101 | 02.03.2021 | 1:20 | 0 | | 101 | 02.03.2021 | 2:40 | 0 | | 101 | 19.06.2021 | 2:05 | 0 | | 101 | 19.06.2021 | 1:45 | 0 | | 101 | 19.06.2021 | 1:25 | 0 | | 101 | 19.06.2021 | 0:45 | 0 |
我希望提取最近2个日期的所有行(可扩展到最近1个、3个等日期),目标结果如下:
| No | Date | hours | Flag | |:------|:-----------|:---------|:----------| | 101 | 02.03.2021 | 1:20 | 0 | | 101 | 02.03.2021 | 2:40 | 0 | | 101 | 19.06.2021 | 2:05 | 0 | | 101 | 19.06.2021 | 1:45 | 0 | | 101 | 19.06.2021 | 1:25 | 0 | | 101 | 19.06.2021 | 0:45 | 0 |
我尝试使用代码:
df.nlargest(2, 'Date', keep='all')
但仅得到最近1个日期的行:
| No | Date | hours | Flag | |:------|:-----------|:---------|:----------| | 101 | 19.06.2021 | 2:05 | 0 | | 101 | 19.06.2021 | 1:45 | 0 | | 101 | 19.06.2021 | 1:25 | 0 | | 101 | 19.06.2021 | 0:45 | 0 |
请问该如何解决这个问题?
解决方法
问题根源有两个:
- Date列是字符串类型而非日期类型:字符串按字符顺序排序,比如
"19.06.2021"首字符'1'比"02.03.2021"的'0'大,但日期逻辑里02.03.2021早于19.06.2021,字符串排序无法正确识别日期先后。 - nlargest的逻辑误解:
nlargest(2, 'Date')是取前2个最大的Date值对应的行,而非前2个唯一日期的所有行。
步骤1:转换Date列为日期类型
先把字符串格式的日期转为Pandas可识别的日期类型,指定格式为dd.mm.yyyy:
df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%Y')
步骤2:获取最近N个唯一日期
提取排序后的前N个唯一日期(以N=2为例):
top_n = 2 top_dates = df['Date'].drop_duplicates().nlargest(top_n).tolist()
步骤3:筛选目标行
用isin方法筛选出这些日期对应的所有行:
result = df[df['Date'].isin(top_dates)]
完整代码示例
import pandas as pd # 构造示例DataFrame data = { 'No': [101]*10, 'Date': ['13.01.2021', '13.01.2021', '15.02.2021', '16.02.2021', '02.03.2021', '02.03.2021', '19.06.2021', '19.06.2021', '19.06.2021', '19.06.2021'], 'hours': ['2:45', '1:20', '3:15', '0:30', '1:20', '2:40', '2:05', '1:45', '1:25', '0:45'], 'Flag': [0]*10 } df = pd.DataFrame(data) # 转换日期类型 df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%Y') # 获取最近2个日期 top_n = 2 top_dates = df['Date'].drop_duplicates().nlargest(top_n).tolist() # 筛选结果 result = df[df['Date'].isin(top_dates)] # 可选:将日期转回原字符串格式 result['Date'] = result['Date'].dt.strftime('%d.%m.%Y') print(result.to_markdown(index=False))
运行后即可得到目标结果,修改top_n的值就能提取最近1个、3个等任意数量的日期行。
内容的提问来源于stack exchange,提问作者Quax
相关产品推荐
相关产品推荐

