Pandas如何将父行套餐价格分摊至对应的子商品行
Pandas实现父子行结构套餐价格分摊
规则说明
数据集为父子行顺序存储结构:
- 每条父行后紧跟其归属的所有子行,父行存储套餐整体信息,子行存储套餐内单条商品明细
- 父行
price字段为套餐总价格,所有子行price字段取值为0 - 父行判定规则:行的
P列取值与package列取值相等时,该行即为父行 - 不同套餐包含的子行数量不固定,无法通过固定大小窗口函数计算,需将父行套餐总价分摊至对应所有子行,结果存入新增列
实现代码
核心逻辑是通过父行位置累计生成分组ID,让所有子行自动关联到所属套餐,再完成分摊计算:
import pandas as pd # 替换为自身数据集读取逻辑,示例为测试构造数据 df = pd.DataFrame([ ["P001", "P001", 100, "套餐A"], ["P001", "S001", 0, "商品1"], ["P001", "S002", 0, "商品2"], ["P002", "P002", 150, "套餐B"], ["P002", "S003", 0, "商品3"], ["P002", "S004", 0, "商品4"], ["P002", "S005", 0, "商品5"], ], columns=["P", "package", "price", "goods_name"]) # 识别父行,累计生成套餐分组ID,子行自动继承最近父行的分组标记 df["package_group"] = (df["P"] == df["package"]).cumsum() # 按分组提取套餐总价、统计组内子行总数 df["package_total"] = df.groupby("package_group")["price"].transform("max") df["sub_item_count"] = df.groupby("package_group")["price"].transform("count") - 1 # 剔除父行本身 # 计算分摊金额,默认子行均摊,父行分摊值设为0,可按需调整 df["apportion_price"] = df.apply( lambda row: 0 if row["P"] == row["package"] else round(row["package_total"] / row["sub_item_count"], 2), axis=1 ) # 删除计算用的中间列 df = df.drop(columns=["package_group", "package_total", "sub_item_count"])
调整说明
- 若需按子行属性(如商品原价、重量)按比例分摊,只需调整
apportion_price计算逻辑:先按分组计算每个子行的分摊权重,再乘以套餐总价即可 - 若需父行保留套餐总价,将lambda逻辑中父行的返回值从0替换为
row["package_total"] - 若数据集未按父子顺序排列,需先按业务排序字段(如行号、下单时间)排序后再执行分组逻辑,避免分组错位
输出示例
代码运行后得到的结果结构如下:
| P | package | price | goods_name | apportion_price |
|---|---|---|---|---|
| P001 | P001 | 100 | 套餐A | 0 |
| P001 | S001 | 0 | 商品1 | 50.0 |
| P001 | S002 | 0 | 商品2 | 50.0 |
| P002 | P002 | 150 | 套餐B | 0 |
| P002 | S003 | 0 | 商品3 | 50.0 |
| P002 | S004 | 0 | 商品4 | 50.0 |
| P002 | S005 | 0 | 商品5 | 50.0 |
内容的提问来源于stack exchange,提问作者Karthik Kumar Premkumar
相关产品推荐
相关产品推荐

