Pandas迭代DataFrame时基于列信息复制行并修改列值问题
DataFrame按季度字典拆分行并分配数值列问题修正
问题说明
现有包含quarter、value、distribution及40+其他列的DataFrame,需求如下:
- 根据
distribution字典中的季度条目数量复制对应行数 - 将指定数值列(如
value)按对应季度的天数占比拆分(示例中0.5×(91/(91+91))=0.25) - 保留原DataFrame所有列
- 支持后续灵活添加/移除数值列,用循环实现
当前代码能生成正确行数,但存在两个核心问题:
- 所有拆分后行内容完全重复:因为循环中直接修改并添加原
row对象(引用传递),最终列表里的都是同一个对象的引用 - 数值计算错误:每次循环都在已修改的
row[value]基础上再次相乘,导致结果被多次放大/缩小(示例中得到0.125而非预期的0.25)
错误代码回顾
rows_list = [] for index, row in df.iterrows(): distribution = [[x[0], x[1]] for x in list(row[distribution].items())] total_days = sum([x[1] for x in distribution]) for quarter in distribution: percentage = quarter[1] / total_days quarter.append(percentage) row[quarter] = quarter[0] row[value] = row[value] * quarter[2] rows_list.append(row) new_df = pd.DataFrame(data=rows_list)
修正后的代码
核心改进点:每次循环创建行副本、基于原始值计算拆分后数值、明确配置数值列列表
import pandas as pd # 定义需要拆分的数值列(后续可直接添加/移除) NUMERIC_COLS = ['value'] rows_list = [] for index, row in df.iterrows(): # 解析distribution字典为季度-天数列表 dist_items = list(row['distribution'].items()) total_days = sum(day for qtr, day in dist_items) # 遍历每个季度条目 for qtr, days in dist_items: # 创建原行的副本,避免修改原对象影响后续循环 new_row = row.copy() # 计算当前季度的天数占比 ratio = days / total_days # 更新quarter列为当前季度 new_row['quarter'] = qtr # 对所有数值列按占比拆分 for col in NUMERIC_COLS: new_row[col] = row[col] * ratio # 将处理后的行加入列表 rows_list.append(new_row) new_df = pd.DataFrame(rows_list)
测试示例
测试DataFrame代码
# 构造测试数据 data = { 'quarter': ['2024Q2'], 'value': [0.5], 'distribution': [{'2024Q1': 91, '2024Q2': 91}], 'type': ['MCF'], 'other_col': ['XYZ'] } df = pd.DataFrame(data)
预期输出
| quarter | value | distribution | type | other_col |
|---|---|---|---|---|
| 2024Q1 | 0.25 | {'2024Q1': 91, '2024Q2':91} | MCF | XYZ |
| 2024Q2 | 0.25 | {'2024Q1': 91, '2024Q2':91} | MCF | XYZ |
内容的提问来源于stack exchange,提问作者Binchentso
相关产品推荐
相关产品推荐

