Anaconda Python3.11高版本df.loc新增DataFrame列报错求助
pandas 2.1.4中df.loc动态新增列触发KeyError的解决方案
问题背景
在Anaconda 2024.02(Python 3.11,对应pandas 2.1.4)环境下,执行my_df.loc[my_df['Name'] == x1, 'newName'] = x1为DataFrame指定行新增列时,触发KeyError: 'newName',报错回溯如下:
Traceback (most recent call last): File "my.py", line 293, in <module> ... File "utils.py", line 961, in update_dataframe_with_new_data my_df.loc[my_df['Name'] == x1, 'newName'] = x1 ~~~~~~~~~~^^^^^^^^^^^^ File "/apps/anaconda/2024.02/lib/python3.11/site-packages/pandas/core/frame.py", line 3893, in __getitem__ indexer = self.columns.get_loc(key) ^^^^^^^^^^^^^^^^^^^^^^^^^ File "/apps/anaconda/2024.02/lib/python3.11/site-packages/pandas/core/indexes/range.py", line 418, in get_loc raise KeyError(key) KeyError: 'newName'
该操作在pandas 1.5.3(Anaconda 2023.07)中正常执行,且预先执行my_df['newName'] = np.nan初始化列也无法解决问题,需实现动态新增列(列名无法预先确定)的可行方案。
解决方案
1. 先通过assign新增列再更新
使用assign方法安全新增列,避免loc直接引用不存在的列:
# 静态列名 my_df = my_df.assign(newName=np.nan) my_df.loc[my_df['Name'] == x1, 'newName'] = x1 # 动态列名(列名存于变量col_name) col_name = 'newName' my_df = my_df.assign(**{col_name: np.nan}) my_df.loc[my_df['Name'] == x1, col_name] = x1
2. 使用df.at定位更新
at支持直接为不存在的列赋值,自动创建新列:
# 单一行更新(取第一个匹配行) row_idx = my_df[my_df['Name'] == x1].index[0] my_df.at[row_idx, 'newName'] = x1 # 多行更新 for row_idx in my_df[my_df['Name'] == x1].index: my_df.at[row_idx, 'newName'] = x1
3. 禁用Copy-on-Write模式
pandas 2.0+默认启用的Copy-on-Write模式可能改变列创建逻辑,临时禁用可恢复旧行为:
import pandas as pd pd.options.mode.copy_on_write = False # 执行赋值操作 my_df.loc[my_df['Name'] == x1, 'newName'] = x1 # 按需恢复原设置 pd.options.mode.copy_on_write = True
注意:禁用该模式可能影响性能,需根据业务场景权衡。
4. 全行列初始化后更新
通过loc[:, col_name]初始化列,避免视图/副本导致的初始化失效:
# 静态列名 my_df.loc[:, 'newName'] = np.nan my_df.loc[my_df['Name'] == x1, 'newName'] = x1 # 动态列名 col_name = 'newName' my_df.loc[:, col_name] = np.nan my_df.loc[my_df['Name'] == x1, col_name] = x1
内容的提问来源于stack exchange,提问作者Shane
相关产品推荐
相关产品推荐

