如何更简洁优雅地按Key和小时筛选DataFrame并保留最大日期记录?
嘿,我来分享几个比你原来的“分组取最大再合并”更简洁优雅的实现方式,都是Pandas里的常用技巧,效率也更高~
先拿一段示例数据来演示(假设你的DataFrame结构类似这样):
import pandas as pd # 模拟你的数据结构 data = { 'Key': [1,1,1,2,2,3], 'Date': ['2024-05-20 10:30:00', '2024-05-20 10:45:00', '2024-05-20 11:15:00', '2024-05-20 09:20:00', '2024-05-20 09:50:00', '2024-05-20 12:00:00'], 'Value': [10, 20, 30, 40, 50, 60] } df = pd.DataFrame(data) df['Date'] = pd.to_datetime(df['Date']) Keys2Filter = (1,2)
方法1:用groupby + idxmax直接定位目标行
这个方法逻辑清晰,先筛选出指定Key的行,再按Key和Date的小时分组,直接取每组中Date最大的那一行的索引,一步拿到结果:
# 先筛选符合条件的Key filtered = df[df['Key'].isin(Keys2Filter)] # 按Key和小时分组,取每组Date最大的行的索引,再提取对应数据 result = filtered.loc[filtered.groupby(['Key', filtered['Date'].dt.hour])['Date'].idxmax()]
这种写法性能很棒,适合处理大数据量,而且不需要额外的中间步骤。
方法2:链式调用sort_values + drop_duplicates
这种写法更紧凑,全程链式操作,不用拆分步骤,代码看起来更清爽:
result = (df[df['Key'].isin(Keys2Filter)] # 新增小时列(临时用于分组去重) .assign(Hour=lambda x: x['Date'].dt.hour) # 按Key、小时、Date排序,保证最大的Date在每组最后 .sort_values(['Key', 'Hour', 'Date']) # 按Key和小时去重,保留最后一行(也就是Date最大的) .drop_duplicates(['Key', 'Hour'], keep='last') # 删掉临时的Hour列 .drop('Hour', axis=1))
如果追求极致简洁,也可以不用新增临时列,直接在排序和去重里引用Date.dt.hour:
result = (df[df['Key'].isin(Keys2Filter)] .sort_values(['Key', df['Date'].dt.hour, 'Date']) .drop_duplicates(subset=['Key', df['Date'].dt.hour], keep='last'))
这两种方法都避免了你原来的“分组取最大再合并”的额外步骤,直接精准定位到需要保留的行,代码更简洁,执行效率也更高~
内容的提问来源于stack exchange,提问作者pofpof
相关产品推荐
相关产品推荐

