Pandas DataFrame新增ot列赋值打印报KeyError如何解决
报错成因
触发KeyError的核心原因是ot列在访问时还未在DataFrame中创建:Pandas不会在对不存在列的索引位置做赋值时自动新建列,直接访问不存在的列名必然抛出KeyError。
额外说明:就算提前创建了ot列,代码里df['ot'].iloc[i] = xxx的写法属于链式索引赋值,是Pandas官方明确不推荐的用法,大概率触发SettingWithCopyWarning,且赋值操作可能不会实际写入原DataFrame,结果不可控。另外逐行写for循环计算列值的写法性能极差,数据量较大时运行速度会比Pandas原生向量化计算慢几个数量级。
正确实现方案
优先使用Pandas原生向量化运算实现,不需要写循环,代码简洁、运行效率高、无索引副作用:
# shift(-1)可直接取到每一行下一行的Open值,和原有计算逻辑完全一致 df['ot'] = (df['Open'] - df['Open'].shift(-1)) / df['Open'].shift(-1) # 最后一行无对应下一行数据,计算结果为NaN,不需要可直接删除 # df = df.dropna(subset=['ot']) print(df['ot'])
如果有特殊场景必须用循环实现(非常不推荐),需要先初始化ot列,同时用loc做单步索引赋值,避免链式索引问题:
import numpy as np # 先初始化和DataFrame长度一致的ot列,填充空值 df['ot'] = np.nan for i in range(len(df)-1): # 用loc同时定位行索引和列名,单步索引赋值不存在链式操作问题 df.loc[i, 'ot'] = (df.loc[i, 'Open'] - df.loc[i+1, 'Open']) / df.loc[i+1, 'Open'] print(df['ot'])
日常使用Pandas做列计算时,优先用内置向量化方法,仅当逻辑无法向量化时再考虑
apply,尽量避免写原生Python for循环逐行操作,二者的性能差距会随数据量增长急剧拉大。
内容的提问来源于stack exchange,提问作者plkj
相关产品推荐
相关产品推荐

