使用df.itertuples()和列名访问pandas单元格值出现AttributeError如何解决
报错原因
你写row.col时,Python会直接尝试访问row这个namedtuple对象中名为col的属性,而不会把你定义的col变量的实际值作为属性名去查找。你的行对象中只有对应列名的属性,不存在名为col的属性,因此抛出AttributeError。
额外说明:如果你的列名是数字、包含特殊字符等不符合Python变量命名规范的内容,pandas生成namedtuple时会自动对列名做转义(比如列名1会被转为_1),直接用原始列名做属性名访问也会出错。
可用解决方案
所有方案运行速度均远高于iterrows(),适配列数多、无法提前获知列名的场景。
方案1:用getattr动态获取属性(代码修改量最小)
通过getattr方法动态传入属性名取值,针对数字列名自动处理转义规则即可:
for row in input_df.itertuples(): print(row.Index) for col in input_df.columns: # 数字列名转义后前缀会加下划线,非数字列名直接用原始值 attr_name = f"_{col}" if isinstance(col, int) else col print(getattr(row, attr_name))
方案2:返回普通元组遍历(速度最快、兼容性最好)
调用itertuples时设置name=None,会返回普通元组而非namedtuple,第一位是索引值,后续元素按列顺序排列,提前生成列名到位置的映射即可避免属性名转义问题:
# 提前生成列名到元组位置的映射,避免循环中重复计算 col_pos_map = {col: idx+1 for idx, col in enumerate(input_df.columns)} for row in input_df.itertuples(name=None): # 元组第一位为索引值 print(row[0]) for col in col_pos_map: print(row[col_pos_map[col]])
方案3:转为字典遍历(写法最直观)
如果习惯键值对取值逻辑,可以用to_dict方法转为字典列表,配合索引遍历:
for idx, row_data in zip(input_df.index, input_df.to_dict("records")): print(idx) for col in input_df.columns: print(row_data[col])
内容的提问来源于stack exchange,提问作者Ritu
相关产品推荐
相关产品推荐

