遍历DataFrame(itertuples/iterrows)时,如何无需df.at/df.loc访问更新的上一行数据?
优化方案:用变量缓存上一行计算结果
完全可以避免反复通过索引访问DataFrame单元格,核心思路是用普通变量缓存上一行的计算结果,而非每次从DataFrame中读取,以此大幅减少IO开销,提升性能。
优化后代码示例
import pandas as pd import numpy as np df = pd.DataFrame({"Column 0": [1,2,3,4,5,6,7,8,9,10]}) # 初始化目标列 df["Column1"] = np.nan df["Column2"] = np.nan df["Column3"] = np.nan # 初始化第一行值,同时缓存到变量 prev_col1 = 0 prev_col2 = 1 prev_col3 = 10 df.loc[0, ["Column1", "Column2", "Column3"]] = [prev_col1, prev_col2, prev_col3] # 从第二行开始遍历计算 for idx in range(1, len(df)): current_col0 = df.iloc[idx]["Column 0"] # 用缓存的上一行值计算当前行 curr_col1 = prev_col2 + prev_col3 curr_col2 = curr_col1 + prev_col3 curr_col3 = curr_col2 * current_col0 + prev_col1 # 批量更新DataFrame当前行 df.loc[idx, ["Column1", "Column2", "Column3"]] = [curr_col1, curr_col2, curr_col3] # 更新缓存变量,为下一行计算做准备 prev_col1, prev_col2, prev_col3 = curr_col1, curr_col2, curr_col3
性能提升原因
- 避免频繁的DataFrame单元格访问:
df.at/df.loc的单单元格访问涉及索引查找、类型转换等额外开销,用普通变量直接读取内存值,速度提升明显。 - 批量赋值减少IO操作:用
df.loc[idx, [列名]]批量更新整行目标列,比多次单独调用df.at更高效。
多列场景扩展方案
如果需要计算的列数量极多,可改用字典或列表缓存上一行所有值,便于扩展维护:
import pandas as pd import numpy as np df = pd.DataFrame({"Column 0": [1,2,3,4,5,6,7,8,9,10]}) target_cols = ["Column1", "Column2", "Column3"] for col in target_cols: df[col] = np.nan # 初始化缓存字典 prev_vals = {"Column1": 0, "Column2": 1, "Column3": 10} df.loc[0, target_cols] = list(prev_vals.values()) for idx in range(1, len(df)): current_col0 = df.iloc[idx]["Column 0"] curr_vals = {} # 按依赖关系计算当前行各列值 curr_vals["Column1"] = prev_vals["Column2"] + prev_vals["Column3"] curr_vals["Column2"] = curr_vals["Column1"] + prev_vals["Column3"] curr_vals["Column3"] = curr_vals["Column2"] * current_col0 + prev_vals["Column1"] # 批量更新DataFrame df.loc[idx, target_cols] = list(curr_vals.values()) # 更新缓存 prev_vals = curr_vals.copy()
内容的提问来源于stack exchange,提问作者Lucas McMaster
相关产品推荐
相关产品推荐

