如何用Pandas按日期范围与类别分组汇总权重列?
高效实现按日期和类别汇总权重的Pandas方案
这里提供一种基于Pandas向量化操作的高效实现,避免嵌套循环的性能损耗,核心思路是先展开每个批次对应的日期范围,再通过分组聚合完成汇总:
import pandas as pd # 初始化原始数据 batches_data = { "XX001": {"category": "AAA", "start_day": pd.Timestamp("2022-01-06"), "end_day": pd.Timestamp("2022-01-14")}, "XX002": {"category": "BBB", "start_day": pd.Timestamp("2022-01-08"), "end_day": pd.Timestamp("2022-01-12")}, "XX003": {"category": "AAA", "start_day": pd.Timestamp("2022-01-07"), "end_day": pd.Timestamp("2022-01-09")}, } batches = pd.DataFrame.from_dict(batches_data, orient="index").reset_index(names="batch") batches["duration"] = (batches["end_day"] - batches["start_day"]).dt.days batches["weight"] = 1 / batches["duration"] # 1. 为每个批次生成对应的日期序列(匹配原逻辑:date < end_day,故排除end_day) batches["date_range"] = batches.apply( lambda x: pd.date_range(start=x["start_day"], end=x["end_day"] - pd.Timedelta(days=1), freq="D"), axis=1 ) # 2. 展开日期序列,将每个日期与批次的类别、权重绑定 expanded_df = batches.explode("date_range").rename(columns={"date_range": "day"}) # 3. 按日期和类别分组,汇总权重 aggregated = expanded_df.groupby(["day", "category"])["weight"].sum().reset_index() # 4. 转换为目标宽表格式,缺失值填充为0 result = aggregated.pivot(index="day", columns="category", values="weight").fillna(0) # 可选:格式化小数位数匹配示例 result = result.round(4) print(result)
关键步骤说明:
- 展开日期范围:通过
apply结合pd.date_range为每个批次生成对应日期序列,再用explode将列表型日期展开为逐行记录,全程是向量化操作,比手动循环高效数倍。 - 分组聚合:利用
groupby(["day", "category"])直接按维度汇总权重,Pandas的分组逻辑经过底层优化,性能远优于逐行判断的循环。 - 重塑宽表:
pivot将长表转换为目标的宽表结构,fillna(0)确保无权重的日期-类别组合显示为0,完全匹配需求格式。
性能优势:
当数据量较大时(比如上百个批次、跨数月的日期范围),这种方法的性能提升会非常显著,彻底规避了嵌套循环中逐行逐日期判断的冗余操作,完全利用Pandas的向量化运算特性。
内容的提问来源于stack exchange,提问作者multipitch
相关产品推荐
相关产品推荐

