Python循环生成值赋值pandas DataFrame列未填充问题咨询
问题根因
df['New'] = New填充不符合预期,是三个写法逻辑错误导致的:
- 你初始创建的
df = pd.DataFrame()是没有任何行、没有索引的空表,这种情况下给df['New']传单个整数(也就是你代码里的标量变量New),pandas只会生成一个长度为1的列,整列都填成你当前传的那个数值,根本存不下循环迭代产生的多个结果。 - 赋值位置放错了。你把这句赋值写在了遍历列的内层循环里,相当于每扫过一行里的某一个单元格,就把整个
New列全部重写一遍,根本不是等一整行处理完、算好这行最终的New值之后存一行结果。等两层循环全跑完,整个New列只会留下最后一次循环算出来的New值,前面所有迭代算出来的结果全被覆盖了。 - 循环里反复给整列赋值的写法本身性能很差,每次赋值pandas都会重写整列数据,数据量稍微大一点运行速度会非常慢。
修正方案
选任意一种符合你使用习惯的写法即可:
方案1:先收集结果再一次性生成DataFrame(性能最优,推荐)
不要在循环里反复操作DataFrame,先用列表把每行算好的最终New值存起来,循环结束后一次性构造表,运行效率最高:
New = 0 Approved = 0 new_values = [] # 用列表存储每行计算得到的最终New值 for row_idx, rowdata in enumerate(combined): for col, value in enumerate(rowdata.values()): if col == 0: print(value) if col == 2: New += value print('Original New') print(value) if col == 4: Approved = value if Approved > 0: New = New - Approved print('Updated New') print(New) # 等当前行所有New值相关逻辑跑完,拿到最终结果后再存入列表 new_values.append(New) # 所有行处理完成后一次性生成DataFrame df = pd.DataFrame({'New': new_values})
方案2:提前初始化固定长度的DataFrame,按行索引赋值
如果需要在循环过程中就把结果写入DataFrame,可以先按数据总行数初始化空表,处理完一行就给对应行位置赋值:
New = 0 Approved = 0 # 提前按combined的总行数初始化带空值的DataFrame df = pd.DataFrame(index=range(len(combined)), columns=['New']) for row_idx, rowdata in enumerate(combined): for col, value in enumerate(rowdata.values()): if col == 0: print(value) if col == 2: New += value print('Original New') print(value) if col == 4: Approved = value if Approved > 0: New = New - Approved print('Updated New') print(New) # 处理完当前行所有计算逻辑后,给对应行索引的位置赋值 df.loc[row_idx, 'New'] = New
注意:不要在遍历列的内层循环中执行结果写入操作,一定要等当前行所有涉及New值计算的判断逻辑(即col2、col4的分支)全部执行完,拿到该行最终的New结果后再写入存储,否则会存入未计算完成的中间错误值。
内容的提问来源于stack exchange,提问作者user17582908
相关产品推荐
相关产品推荐

