Pandas DataFrame赋值异常:调整列顺序后C列才生效,是Bug吗?
Pandas 2.0.3中列顺序影响.loc赋值的问题分析
问题场景
我有一个名为df的DataFrame,包含布尔类型的to_be_pred列(取值为True/False)。先筛选出to_be_pred为True的行生成df_temp并做操作,之后尝试将df_temp的值回赋给df:
df_temp = df[df['to_be_pred']].copy() # 对df_temp执行一些操作 df.loc[df['to_be_pred'], ['A', 'B', 'to_be_pred', 'C']] = df_temp[['A', 'B', 'to_be_pred', 'C']]
此时df的A、B、to_be_pred列能正确更新,但C列赋值失败。调整列顺序后,问题解决:
df.loc[df['to_be_pred'], ['A', 'B', 'C', 'to_be_pred']] = df_temp[['A', 'B', 'C', 'to_be_pred']]
问这是不是Pandas的Bug?使用版本为pd.__version__: '2.0.3'
问题分析
这不是Pandas的Bug,而是由Pandas的索引对齐和赋值顺序逻辑导致的:
- 行筛选的布尔掩码
df['to_be_pred']是在赋值操作启动前就计算完成的,属于静态条件,不会被后续列的赋值改变。 - 当
cols列表中包含to_be_pred列且它位于C列之前时,Pandas会按列顺序依次执行赋值。完成to_be_pred列的赋值后,后续处理C列时,内部对齐逻辑因目标列与行筛选条件列同名,出现匹配偏差,导致C列的赋值未能正确覆盖目标行。 - 把
to_be_pred列移到列列表最后时,其他列(包括C)先完成赋值,不会受到该列赋值的干扰,对齐逻辑正常运行。
解决方案
- 无需赋值
to_be_pred列:df_temp本身就是从df中筛选to_be_pred为True的行生成的,该列值无需重复回写,可简化代码:
df.loc[df['to_be_pred'], ['A', 'B', 'C']] = df_temp[['A', 'B', 'C']]
- 如果必须包含
to_be_pred列,将其放在列列表的最后位置即可。
内容的提问来源于stack exchange,提问作者Elif Berkman
相关产品推荐
相关产品推荐

