无法修改从Excel读取的Pandas DataFrame问题求助
问题原因及解决办法
核心原因
1. Pandas apply的行传递机制差异
手动构造的df_test1、df_test2在内存中属于原生连续结构,apply传递的行对象是原DataFrame的视图,修改row会直接同步到原数据。但从Excel读取的df_test3,由于加载时的内存布局或类型转换逻辑,apply传递的是行的副本,修改副本不会影响原DataFrame。
2. 浮点数精度误差
Excel读取的浮点数可能存在微小的二进制存储舍入误差,导致sum(values)==total的严格相等判断不成立,函数根本没进入修改逻辑——即便你视觉上验证df_test2和df_test3数据一致,实际二进制层面仍可能存在差异。
解决办法
方案1:修改函数逻辑,返回新行并重新赋值
放弃依赖原地修改行对象的方式,让函数返回修改后的行,再将apply结果重新赋值给原DataFrame,同时修复精度判断问题:
import pandas as pd from itertools import combinations def find_match_total(row, total_col, sum_cols): # 修正size取值:仅统计sum_cols的长度,而非整行长度 size = len(sum_cols) data = row.loc[row.index.isin(sum_cols)].to_dict() total = row[total_col] keys = data.keys() values = data.values() break_outer_loop = False for i in range(2, size+1): if break_outer_loop: break key_combinations = combinations(keys, i) value_combinations = combinations(values, i) for cols, vals in zip(key_combinations, value_combinations): # 用近似相等判断替代严格相等,解决浮点数精度问题 if abs(sum(vals) - total) < 1e-6: break_outer_loop = True print(cols, vals) # 复制row避免视图/副本的歧义问题 row = row.copy() for key in sum_cols: if key not in cols: # 用Pandas官方工具判断数据类型,更可靠 row[key] = 0.0 if pd.api.types.is_float_dtype(row[key]) else 0 break return row # 执行apply并重新赋值给原DataFrame df_test1 = df_test1.apply(find_match_total, args=('c',['a','b','x']), axis=1) df_test2 = df_test2.apply(find_match_total, args=('c',['a','b','x']), axis=1) df_test3 = df_test3.apply(find_match_total, args=('c',['a','b','x']), axis=1)
额外优化说明
- 原代码中
size = len(row)属于逻辑错误,应改为仅统计sum_cols的长度,避免遍历不必要的组合。 - 使用
pd.api.types.is_float_dtype替代直接判断dtype == 'float64',适配更多浮点类型场景。
内容的提问来源于stack exchange,提问作者Dinh Quang Tuan
相关产品推荐
相关产品推荐

