使用pd.DataFrame.itertuples不自动修正列名
何为pandas.DataFrame.itertuples?
相较于 pandas.DataFrame.iterrows而言,pandas.DataFrame.itertuples更好地提供了按行遍历DataFrame 的功能,详见pandas——按行遍历dataframe的优选方法(itertuples,iterrows)
这这里,我们需要了解的是,itertuples返回的是一个namedtuple迭代器。同时可以传递两个参数:name和index。其中,index决定了是否包含索引,而name决定了namedtuple的名称。
何为namedtuple?
那么到这里,就需要提到关于namedtuple的基本信息。
可以查看python——什么是namedtuple?了解它,理解它,掌握它
一旦了解过namedtuple后,我们就可以知道namedtuple有一个参数:rename。这个参数决定了是否将无效的字段名自动替换为位置名称。
问题所在
先看一下pandas.DataFrame.itertuples的源代码,方便起见我只摘取需要关注的一部分:
def itertuples(
self, index: bool = True, name: str | None = "Pandas", rename: bool = True
) -> Iterable[tuple[Any, ...]]:
arrays = []
fields = list(self.columns)
if index:
arrays.append(self.index)
fields.insert(0, "Index")
arrays.extend(self.iloc[:, k] for k in range(len(self.columns)))
if name is not None:
# https://github.com/python/mypy/issues/9046
# error: namedtuple() expects a string literal as the first argument
itertuple = collections.namedtuple( # type: ignore[misc]
name, fields, rename=True
)
return map(itertuple._make, zip(*arrays))
# fallback to regular tuples
return zip(*arrays)
如上所示,它直接定义了rename=True,也就默认让itertuples自动修正无效的字段名。
那么我们就需要将rename参数重新在itertuples中恢复,同时也不能影响pandas的正常使用
解决办法
直接将 rename=True改为rename=False即可。
友情提示
rename这个参数为True时,可以自动修正。但为False时,如果列名不符合python的命名规则,直接报错,并不是按照原名称进行输出。所以在使用时谨慎使用。