如何基于最大装载量将pandas DataFrame订单数据拆分为多行?
报错原因
你原来的代码存在两个核心问题:
- 字段名拼写误差:原始输入数据的字段为
max_eligability,代码中误写为max_eligibility,会直接触发字段不存在的报错 order_splits赋值逻辑错误:你是将整列的重复结果和余数拼成了全局元组,没有为每行单独生成可拆分的列表结构,导致explode无法按行正常拆分
实现方案
方案1:修复后的explode实现(中小数据量适用,逻辑易维护)
通过行级apply生成每行对应的拆分托盘数列表,再用explode拆分,逻辑简单好理解:
import pandas as pd def planned_routes(df): df = df.copy() # 避免修改原始DataFrame # 每行生成拆分后的托盘数列表 df['order_splits'] = df.apply( lambda row: [row['max_eligability']]*(row['pallets']//row['max_eligability']) + ([row['pallets']%row['max_eligability']] if row['pallets']%row['max_eligability']>0 else []), axis=1 ) df = df.explode('order_splits') # 清理冗余字段,重命名拆分后的托盘数字段 df = df.drop(['pallets', 'max_eligability'], axis=1).rename(columns={'order_splits': 'pallets'}) return df
方案2:向量化高速实现(大数据量适用,性能更优)
不用逐行遍历,完全基于pandas原生向量化操作,数据量越大性能优势越明显,比apply方案快5~10倍:
import pandas as pd import numpy as np def planned_routes_fast(df): df = df.copy() # 计算每个原订单需要拆分的总条数 df['split_cnt'] = (df['pallets'] + df['max_eligability'] - 1) // df['max_eligability'] # 按拆分条数重复行生成扩展表 df_expand = df.loc[df.index.repeat(df['split_cnt'])].reset_index(drop=True) # 生成同原订单内的拆分订单序号 df_expand['rn'] = df_expand.groupby(level=0).cumcount() + 1 # 计算拆分后的托盘数:非最后一行取最大装载量,最后一行取余数 df_expand['pallets'] = np.where( df_expand['rn'] < df_expand['split_cnt'], df_expand['max_eligability'], df_expand['pallets'] - (df_expand['split_cnt']-1)*df_expand['max_eligability'] ) # 清理辅助字段 df_expand = df_expand.drop(['max_eligability', 'split_cnt', 'rn'], axis=1) return df_expand
输出示例
用你提供的输入数据运行后,输出结果如下:
| date | shipper_id | pallets |
|---|---|---|
| 2021-12-01 | S1 | 24 |
| 2021-12-01 | S1 | 24 |
| 2021-12-01 | S1 | 2 |
| 2021-12-01 | S2 | 14 |
| 2021-12-01 | S2 | 11 |
| 2021-12-02 | S1 | 24 |
| 2021-12-02 | S1 | 24 |
| 2021-12-02 | S1 | 24 |
| 2021-12-02 | S1 | 3 |
| 2021-12-02 | S2 | 14 |
| 2021-12-02 | S2 | 1 |
内容的提问来源于stack exchange,提问作者ggOlle
相关产品推荐
相关产品推荐

