如何使用嵌套for循环向Pandas DataFrame添加计算值?
Pandas嵌套循环计算DataFrame值出错的原因及解决
我有两个存储浮点值的DataFrame:
- 第一个是单列DataFrame,存储位置数据;
- 第二个是矩阵形式的DataFrame,列数等于ID数量,行数与第一个DataFrame完全一致。
需求是创建一个和第二个DataFrame尺寸相同的新DataFrame,其中每个值通过公式 (df1 * df2) / len(df1) + 1 计算,要求先遍历完一列的所有行再处理下一列。
示例数据
import pandas as pd # 输入数据 df1 = pd.DataFrame([10,20,30,40,50,60], columns=['POS']) df2 = pd.DataFrame({"ID1" : [0,2,4,6,8,10] , "ID2" :[1,3,5,7,9,11]}) # 预期输出结果 final = pd.DataFrame({"ID1" : [0, 5.714285714, 17.14285714, 34.28571429, 57.14285714, 85.71428571] , "ID2" :[1.428571429, 8.571428571, 21.42857143, 40, 64.28571429, 94.28571429]})
我尝试的错误代码
final = pd.DataFrame([]) for i in list(range(0,len(df1))): for j in list(range(0,len(df2))): final.append(df2.iloc[i,j] * df1[0][i] / len(df1)+1)
可行的R代码参考
for (i in 1:nrow(df1)){ for (j in 1:ncol(df2)){ final[i,j] <- (df2[i,j] * df1[i,1]) / nrow(df1)+1 } }
错误原因分析
append方法使用错误:Pandas的DataFrame.append()不会修改原对象,而是返回新的DataFrame,你没有接收返回值,且每次传入单个标量会导致结果结构完全不符合预期。- 遍历顺序颠倒:你的循环是先遍历行再遍历列,不符合“先处理完一列所有行再处理下一列”的要求。
- df1取值错误:
df1[0]试图按索引0访问列,但df1的列名是'POS',应该用df1.iloc[i, 0]或df1['POS'].iloc[i]来获取对应行的值。
修正后的循环写法
按照需求的遍历顺序(先列后行),正确初始化并赋值:
import pandas as pd df1 = pd.DataFrame([10,20,30,40,50,60], columns=['POS']) df2 = pd.DataFrame({"ID1" : [0,2,4,6,8,10] , "ID2" :[1,3,5,7,9,11]}) # 初始化和df2尺寸、行列一致的空DataFrame final = pd.DataFrame(index=df2.index, columns=df2.columns) row_count = len(df1) # 先遍历每一列,再遍历列内的每一行 for col_idx in range(len(df2.columns)): col_name = df2.columns[col_idx] for row_idx in range(row_count): # 按公式计算值 calc_val = (df2.iloc[row_idx, col_idx] * df1.iloc[row_idx, 0]) / row_count + 1 final.iloc[row_idx, col_idx] = calc_val print(final)
更高效的向量化实现(推荐)
Pandas原生支持向量化运算,无需循环,代码更简洁且性能更好:
import pandas as pd df1 = pd.DataFrame([10,20,30,40,50,60], columns=['POS']) df2 = pd.DataFrame({"ID1" : [0,2,4,6,8,10] , "ID2" :[1,3,5,7,9,11]}) # 利用广播机制,df1的POS列自动与df2每列对应行相乘 final = (df2.mul(df1['POS'], axis=0) / len(df1)) + 1 print(final)
内容的提问来源于stack exchange,提问作者Paulo Cecco
相关产品推荐
相关产品推荐

