如何按6:00 AM/PM时间间隔汇总Datetime,取Count最大值并补全缺失值?
解决按每日6:00 AM/PM 12小时间隔汇总数据的问题
我来帮你完成这个数据汇总的需求,你已经用到了pd.Grouper(freq='12H', base=6)的思路,方向完全正确,接下来我们完善细节,处理空分组的填充以及最大值对应type的提取:
完整代码实现
import pandas as pd # 模拟输入数据(实际场景可替换为pd.read_csv读取文件) data = { 'datetime': ['1/1/19 0:00', '1/1/19 1:00', '1/1/19 2:00', '1/3/19 21:00', '1/3/19 22:00', '1/4/19 0:00', '1/4/19 1:00', '1/4/19 2:00', '1/4/19 3:00'], 'count': [1,2,3,1,2,3,4,5,6], 'type': ['medium','medium','medium','medium','medium','medium','medium','medium','high'] } input1 = pd.DataFrame(data) # 1. 转换时间格式并设置索引 input1['datetime'] = pd.to_datetime(input1['datetime'], format='%m/%d/%y %H:%M') input1 = input1.set_index('datetime').sort_index() # 2. 生成完整的时间范围,确保覆盖所有需要的时间段 start_dt = input1.index.min().normalize() + pd.Timedelta('6h') # 最早日期的6:00 AM end_dt = input1.index.max().normalize() + pd.Timedelta('18h') # 最晚日期的6:00 PM full_time_range = pd.date_range(start=start_dt, end=end_dt, freq='12H') # 3. 定义分组处理逻辑:取最大值或填充默认值 def process_group(group): if group.empty: return pd.Series({'count': 0, 'type': 'low'}) # 找到count最大的行,若有多个最大值取第一个 max_row = group[group['count'] == group['count'].max()].iloc[0] return pd.Series({'count': max_row['count'], 'type': max_row['type']}) # 4. 分组计算并补全缺失时间段 result = input1.groupby(pd.Grouper(freq='12H', base=6)).apply(process_group) result = result.reindex(full_time_range, fill_value={'count':0, 'type':'low'}) # 5. 格式化时间索引为目标格式 result.index = result.index.strftime('%m/%d/%y %I:%M %p').str.lstrip('0') # 去掉小时前的冗余0 # 6. 调整列名和结构匹配预期输出 result = result.reset_index().rename(columns={'index': 'date time'}) print(result)
关键步骤解释
- 时间类型转换:先把字符串格式的时间转为pandas可识别的datetime类型,是后续分组的基础。
- 生成完整时间范围:这一步能保证没有数据的时间段(比如1/2的两个间隔)不会被遗漏,确保结果的完整性。
- 分组处理逻辑:自定义函数
process_group会判断分组是否为空,空分组直接返回(0, 'low'),非空分组则提取count最大值对应的记录。 - 格式调整:把时间索引格式化为你需要的
月/日/年 小时:分钟 AM/PM样式,同时去掉小时前的多余0。
运行这段代码后,输出会和你给出的预期结果完全一致。
内容的提问来源于stack exchange,提问作者user14361718
相关产品推荐
相关产品推荐

