如何基于df1的cartons/blocks比例为Pandas的df2添加loadgroup列?
按指定占比为数据框分配Load Group
需求背景
已有df1包含loadgroup、纸箱占比(cartons)、托盘占比(blocks)列,明确了1-5号loadgroup各自对应的纸箱和托盘占比;另有df2包含block和cartons列,但无loadgroup字段,总计100个block、29608个cartons。需要为df2的每条记录分配1-5的loadgroup,尽可能贴近df1定义的占比标准。
实现步骤及代码示例
以下用Python pandas给出具体分配方案:
1. 准备基础数据
先定义df1的占比数据(替换为你的真实数值),并加载df2的业务数据:
import pandas as pd import numpy as np # 示例df1:各loadgroup的目标占比(替换为你的真实数据) df1 = pd.DataFrame({ 'loadgroup': [1, 2, 3, 4, 5], 'cartons_pct': [0.26, 0.22, 0.18, 0.17, 0.17], 'blocks_pct': [0.21, 0.20, 0.20, 0.19, 0.20] }) # 加载你的df2真实数据(此处为模拟示例) total_cartons = 29608 total_blocks = 100 df2 = pd.DataFrame({ 'block': range(1, total_blocks + 1), 'cartons': np.random.randint(100, 500, size=total_blocks) # 替换为真实cartons数据 })
2. 计算各Load Group的目标分配数量
根据df1的占比计算每个loadgroup需要分配的blocks数量和对应cartons总量,同时修正取整误差确保总数匹配:
# 计算目标数量并取整 df1['target_blocks'] = (df1['blocks_pct'] * total_blocks).round().astype(int) df1['target_cartons'] = (df1['cartons_pct'] * total_cartons).round().astype(int) # 修正blocks总数偏差 blocks_diff = total_blocks - df1['target_blocks'].sum() if blocks_diff != 0: # 将差值分配给占比最高的组(可按需调整分配逻辑) df1.loc[df1['blocks_pct'].idxmax(), 'target_blocks'] += blocks_diff # 修正cartons总数偏差 cartons_diff = total_cartons - df1['target_cartons'].sum() if cartons_diff != 0: df1.loc[df1['cartons_pct'].idxmax(), 'target_cartons'] += cartons_diff
3. 为df2分配Load Group
通过排序+切片的方式分配,兼顾cartons和blocks的占比要求:
# 按cartons降序排序,让高cartons的block优先匹配对应占比高的loadgroup df2_sorted = df2.sort_values('cartons', ascending=False).reset_index(drop=True) # 生成loadgroup分配列表 loadgroup_list = [] for _, row in df1.iterrows(): loadgroup_list.extend([row['loadgroup']] * row['target_blocks']) # 为df2添加loadgroup字段 df2_sorted['loadgroup'] = loadgroup_list # 验证分配结果的占比 print("实际cartons占比:") print(df2_sorted.groupby('loadgroup')['cartons'].sum() / total_cartons) print("\n实际blocks占比:") print(df2_sorted.groupby('loadgroup').size() / total_blocks)
优化说明
- 如果需要更严格地同时匹配两个指标的占比,可使用线性规划(如
scipy.optimize.linprog)求解最优分配方案,避免排序法可能带来的偏差。 - 取整误差的分配逻辑可根据业务调整,比如分配给当前偏差最小的组,而非占比最高的组。
内容的提问来源于stack exchange,提问作者Lenny
相关产品推荐
相关产品推荐

