rolling.apply执行报错原因分析及代码修改方案咨询
问题排查与修改方案
原代码的错误点
- 拼写错误:函数里的
numertor是笔误,应该是numerator - 分子分母搞反:你的计算式里,分子是
time_node[index]*rate_node[index] - time_node[index-1]*rate_node[index-1],分母是time_node[index]-time_node[index-1],但原函数里把这俩搞反了 rolling.apply的用法错误:rolling.apply传入的函数无法直接接收多列参数(比如你写的rate和time),而且你传的{'rate': 'rate_node', 'time': 'time_node'}不是合法参数格式。当对DataFrame做rolling操作时,每个窗口是一个小的DataFrame,函数需要从这个窗口里提取对应列的值来计算。
修改方案
方案一:修正rolling.apply的用法
调整函数逻辑,让它接收窗口内的DataFrame数组,然后提取time和rate的值计算:
import pandas as pd nodes = [30, 60, 90, 180, 270, 360] rate = [1.67000, 1.82000, 2.13000, 2.53000, 2.68000, 2.71000] df = pd.DataFrame({'time_node': nodes, 'rate_node': rate}) def forward_rate(window): # window是一个2行2列的数组,第一行是前一个数据,第二行是当前数据 time_prev, rate_prev = window[0] time_curr, rate_curr = window[1] numerator = time_curr * rate_curr - time_prev * rate_prev denominator = time_curr - time_prev return numerator / denominator # 对整个DataFrame做rolling(2),然后应用函数 df['forward_rate'] = df.rolling(2).apply(forward_rate, raw=True)
注:raw=True参数会把窗口数据以numpy数组形式传入函数,提升效率。
方案二:用shift方法实现(更高效)
rolling.apply的效率较低,对于这种相邻行的计算,用shift直接计算更简单高效:
import pandas as pd nodes = [30, 60, 90, 180, 270, 360] rate = [1.67000, 1.82000, 2.13000, 2.53000, 2.68000, 2.71000] df = pd.DataFrame({'time_node': nodes, 'rate_node': rate}) # 计算分子:当前行time*rate - 上一行time*rate numerator = df['time_node'] * df['rate_node'] - df['time_node'].shift(1) * df['rate_node'].shift(1) # 计算分母:当前行time - 上一行time denominator = df['time_node'] - df['time_node'].shift(1) # 新增列,第一行因为没有上一行数据,会是NaN df['forward_rate'] = numerator / denominator
运行后得到的结果:
time_node rate_node forward_rate 0 30 1.67 NaN 1 60 1.82 1.970000 2 90 2.13 2.440000 3 180 2.53 2.736667 4 270 2.68 2.830000 5 360 2.71 2.740000
内容的提问来源于stack exchange,提问作者1670511081
相关产品推荐
相关产品推荐

