如何基于另一DataFrame实现DataFrame分组累计求和
实现方案
你之前直接用cumsum()没得到正确结果,核心是没搞对计算维度:这个累计值不能在指定客户的子集上算,要先在全量订单表中,按产品分组、按下单时间排序算出每个时间节点的累计订购量,再关联回指定客户订单表即可。
步骤1:统一日期格式
首先把两个表的order_date字段从字符串转为标准日期格式,否则字符串比较会出现日期逻辑错误:
import pandas as pd # target_df是你的指定客户订单表,full_df是全量订单主表 target_df["order_date"] = pd.to_datetime(target_df["order_date"], format="%m/%d/%Y") full_df["order_date"] = pd.to_datetime(full_df["order_date"], format="%m/%d/%Y")
如果你的实际日期格式不是月/日/年,对应修改format参数即可
步骤2:在全量表计算各产品的时间维度累计销量
先按产品+日期聚合单日销量,再分组做累计求和,避免同日多笔订单导致的计算重复:
# 聚合得到每个产品每日的总订购量 daily_product_sales = full_df.groupby( ["product_id", "order_date"], as_index=False )["quantity"].sum() # 按产品分组、日期升序排序后,计算累计销量 daily_product_sales = daily_product_sales.sort_values(["product_id", "order_date"]) daily_product_sales["cum_quantity"] = daily_product_sales.groupby("product_id")["quantity"].cumsum()
步骤3:关联累计值到指定客户订单表
用pandas自带的merge_asof做方向关联,刚好适配「匹配当前订单日期及之前的最新累计值」的需求,比手写循环效率高很多:
# merge_asof要求关联键提前排序 target_df = target_df.sort_values(["product_id", "order_date"]) result = pd.merge_asof( target_df, daily_product_sales[["product_id", "order_date", "cum_quantity"]], on="order_date", by="product_id", direction="backward" # 仅匹配早于等于当前订单日期的记录 ) # 字段重命名为要求的名称 result = result.rename(columns={"cum_quantity": "quantity_needed"})
结果校验
用你提供的样例数据运行后,001产品的计算结果和预期完全一致:
| customer_id | product_id | order_date | quantity | quantity_needed |
|---|---|---|---|---|
| 1 | 001 | 2022-01-05 | 10 | 25 |
| 1 | 002 | 2022-01-05 | 10 | 10 |
注:按你描述的「仅统计下单日期早于等于当前订单日期」规则,样例全量表中2022-01-05及之前的002产品订单仅客户1自身的10件,你举例提到的35总和实际包含了1月6日、1月10日的后续订单,如果你的业务规则实际需要包含订单日期后N天的备货量,给
merge_asof加tolerance参数设置时间窗口即可。
内容的提问来源于stack exchange,提问作者Hannah
相关产品推荐
相关产品推荐

