Python中带datetime.date行索引的DataFrame逐列求相邻行差的实现与KeyError解决
自定义函数报错的核心原因
- 维度逻辑完全颠倒:需求是逐列做行方向的相邻值差分,即同列下,第N行值 = 第N行累计值 - 第N-1行累计值。但你传
axis=0走的else分支,循环逻辑完全错位:- 用
enumerate(df.columns)得到的x是(列序号, 列名)的元组,根本无法用x == 0判断是不是第一列 - 把
df.iterrows()返回的(行索引, 行数据Series)元组,当成列名去索引赋值,这就是抛出KeyError的直接原因——程序拿一个包含datetime日期、整行数据的元组当列名查值,自然找不到对应键。
- 用
- 基础代码规范问题:
- 变量
cf从未初始化,就算逻辑写对也会报未定义错误 - 函数内的
if axis == 1判断没有做缩进,直接写在函数定义下,运行会触发缩进语法错误
- 变量
- 本次报错和行索引的
datetime.date类型完全无关,属于逻辑错位导致的索引键错误。
无需自定义循环的正确实现
pandas内置方法完全可以覆盖需求,运行效率远高于逐行逐列的Python循环,且对date类型行索引兼容性正常:
- 首行100%保留原累计利润值
- 从第二行开始,逐列计算相邻行的差值(当前行值 - 上一行同列值)
核心代码如下:
# 复制原数据避免修改原始累计值DataFrame pnl_result = original_df.copy() # 第二行开始逐列计算单日损益 pnl_result.iloc[1:, :] = original_df.iloc[1:, :].values - original_df.shift(1).iloc[1:, :].values
*代码中的original_df替换为你实际使用的累计利润DataFrame变量(即示例中的AAAT)即可直接运行。
更简洁的等价写法:先对全表做行方向差分,再把第一行替换回原累计值
pnl_result = original_df.diff(axis=0) pnl_result.iloc[0, :] = original_df.iloc[0, :]
结果匹配校验
按照你给出的计算样例,代码计算结果和预期完全一致:
- 2021-03-2 对应列值 = 76.512615 - (-216.097205) = 292.6098
- 2021-03-3 对应列值 = -645.63337 - 76.512615 = -722.14
内容的提问来源于stack exchange,提问作者Frankie C
相关产品推荐
相关产品推荐

