循环生成DataFrame并合并为大表时的重复数据与计算异常问题
问题分析与解决方案
你遇到的问题核心有两个:
- DataFrame的引用传递陷阱:循环里写
df = df_or时,并没有创建新的DataFrame副本,只是让df指向了原始df_or的内存地址。这意味着每次循环修改df的操作,其实都是直接修改原始的df_or,而且添加到total列表里的都是同一个对象。最后pd.concat的时候,相当于把同一个DataFrame重复拼接了两次,这就是结果里出现重复行的原因。 - 计算时依赖被污染的原始数据:第一次循环
i=0时,你把df_or的A列改成了0(因为df是引用),第二次循环i=1时,用df_or.loc[:, 'A'].mul(i)计算的是已经被改成0的A列,自然结果还是0,这就是乘法操作异常的根源;而加法操作看起来正常,大概率是你之前测试时的代码逻辑不同,但核心问题还是引用导致的原始数据被篡改。
修正后的代码
只需要在循环里创建原始DataFrame的独立副本,确保每次循环操作的都是互不影响的新DataFrame:
import pandas as pd df_or = pd.DataFrame({"Case": [1,2,3,4,5,6], "A": [3,5,2,8,4,1], "B": [10,12,24,8,57,84]}) print("原始DataFrame:") print(df_or) total = [] for i in range(0,2): # 关键修改:创建原始DataFrame的副本,而非引用 df = df_or.copy() # 基于原始df_or的A列计算,保证每次都用初始值 df.loc[:, 'A'] = df_or.loc[:, 'A'].mul(i) df.loc[:, 'ID'] = df.loc[:,'Case'] + i*100000 print(f"\n第{i}次循环后的DataFrame:") print(df) total.append(df) total = pd.concat(total) total = total.sort_values('ID') total.reset_index(inplace=True, drop=True) print("\n最终合并结果:") print(total)
运行结果
这段代码会输出你期望的结果:
原始DataFrame: Case A B 0 1 3 10 1 2 5 12 2 3 2 24 3 4 8 8 4 5 4 57 5 6 1 84 第0次循环后的DataFrame: Case A B ID 0 1 0 10 1 1 2 0 12 2 2 3 0 24 3 3 4 0 8 4 4 5 0 57 5 5 6 0 84 6 第1次循环后的DataFrame: Case A B ID 0 1 3 10 100001 1 2 5 12 100002 2 3 2 24 100003 3 4 8 8 100004 4 5 4 57 100005 5 6 1 84 100006 最终合并结果: Case A B ID 0 1 0 10 1 1 2 0 12 2 2 3 0 24 3 3 4 0 8 4 4 5 0 57 5 5 6 0 84 6 6 1 3 10 100001 7 2 5 12 100002 8 3 2 24 100003 9 4 8 8 100004 10 5 4 57 100005 11 6 1 84 100006
额外说明
- 如果你的DataFrame包含嵌套数据结构(比如列表、字典),可以显式使用
df_or.copy(deep=True)确保完全复制所有层级的数据(默认deep=True,所以直接copy()也足够)。 - 若你希望每次循环基于当前副本的A列计算(而非原始值),可以把
df_or.loc[:, 'A'].mul(i)改成df.loc[:, 'A'].mul(i),不过根据你的期望结果,显然是需要基于原始A列计算的。
内容的提问来源于stack exchange,提问作者Matthi9000
相关产品推荐
相关产品推荐

