如何高效将df1同一客户多类别条目映射到df2对应列单条目中?
高效实现Pandas DataFrame类别金额映射(避免双重循环)
需求说明
现有两个Pandas DataFrame:
- df1:包含
Client、Category、Amount列,同一客户对应多条按类别排列的记录 - df2:包含
Client、Due_Date列,以及与df1的Category同名的列(如Service1、Service2)
需要将df1中同一客户的各类别Amount值映射到df2对应列,要求避免低效的双重循环,实现高效处理。
示例数据
import pandas as pd # 输入数据 df1 = pd.DataFrame({ 'Client': ['Rick', 'Rick', 'John'], 'Category': ['Service1', 'Service2', 'Service1'], 'Amount': [250, 6, 79] }) df2 = pd.DataFrame(columns=['Client', 'Due_Date', 'Service1', 'Service2']) # 期望输出 output = pd.DataFrame({ 'Client': ['Rick', 'John'], 'Due_Date': [None, None], 'Service1': [250, 79], 'Service2': [6, 0] })
高效实现方案
可以通过数据透视(pivot) + 合并(merge) 的方式实现,完全避免循环,利用Pandas的向量化操作提升效率:
步骤1:将df1透视成宽表
先把df1按Client分组,将Category作为列,Amount作为值,生成每个客户对应各类别的金额表:
pivoted_df1 = df1.pivot(index='Client', columns='Category', values='Amount').reset_index()
透视后得到的结构:
| Client | Service1 | Service2 |
|---|---|---|
| John | 79 | NaN |
| Rick | 250 | 6 |
步骤2:合并到df2并处理缺失值
将透视后的表与df2按Client合并,同时把缺失的类别金额填充为0,保留Due_Date列:
- 如果df2已有
Client数据,执行合并:
result = pd.merge(pivoted_df1, df2[['Client', 'Due_Date']], on='Client', how='right').fillna({'Service1':0, 'Service2':0})
- 如果df2初始是空表(如示例),直接基于透视表生成结果:
result = pivoted_df1.assign(Due_Date=None).fillna({col:0 for col in df2.columns if col not in ['Client', 'Due_Date']})
完整代码
import pandas as pd df1 = pd.DataFrame({ 'Client': ['Rick', 'Rick', 'John'], 'Category': ['Service1', 'Service2', 'Service1'], 'Amount': [250, 6, 79] }) df2 = pd.DataFrame(columns=['Client', 'Due_Date', 'Service1', 'Service2']) # 透视df1 pivoted_df1 = df1.pivot(index='Client', columns='Category', values='Amount').reset_index() # 处理空df2的情况,生成结果并对齐列顺序 result = pivoted_df1.assign(Due_Date=None).fillna({col:0 for col in df2.columns if col not in ['Client', 'Due_Date']}) result = result[df2.columns] print(result)
运行后输出与示例output完全一致:
Client Due_Date Service1 Service2 0 John None 79 0 1 Rick None 250 6
方案优势
- 完全基于Pandas的向量化操作,比双重循环效率提升几个数量级,尤其适合大数据集
- 代码简洁易维护,无需手动处理客户和类别的匹配逻辑
- 自动处理缺失类别,通过
fillna可灵活调整填充值
内容的提问来源于stack exchange,提问作者Have_a_great_day
相关产品推荐
相关产品推荐

