Python 熊猫的滚动窗口多项式拟合
我试图从应用于时间序列t日窗口的n次多项式计算系数。但是,我收到一个异常Python 熊猫的滚动窗口多项式拟合,python,numpy,pandas,Python,Numpy,Pandas,我试图从应用于时间序列t日窗口的n次多项式计算系数。但是,我收到一个异常TypeError:只有length-1数组可以转换为Python标量 我的版本是: Python 3.6 熊猫版本0.22.0 numpy版本1.13.3 守则: import pandas as pd import numpy as np my_ts = pd.Series(data = np.random.normal(size = 365 * 2), index = pd.date_range(start = '
TypeError:只有length-1数组可以转换为Python标量
我的版本是:
- Python 3.6
- 熊猫版本0.22.0
- numpy版本1.13.3
守则:
import pandas as pd
import numpy as np
my_ts = pd.Series(data = np.random.normal(size = 365 * 2), index = pd.date_range(start = '2013-01-01', periods = 365 * 2))
coefs = pd.rolling_apply(my_ts, 21, lambda x: np.polyfit(range(len(x)), x, 3))
然而,当我包装np.polyfit
使其只返回一个系数时,rolling\u apply
没有问题
def pf_wrapper(x):
coef_lst = np.polyfit(range(len(x)), x, 3)
return coef_lst[0]
coefs = pd.rolling_apply(my_ts, 21, pf_wrapper)
更新:
由于pd.rolling\u apply()
无法返回非标量,因此我当前的解决方案如下:
def get_beta(ts, deg):
coefs = polyfit(range(len(ts)), ts, deg = 3)[::-1]
return coefs[deg]
b0 = pd.rolling_apply(my_ts, 21, lambda x: get_beta(x, 0))
...
b3 = pd.rolling_apply(my_ts, 21, lambda x: get_beta(x, 3))
我认为使用滚动应用是不可能的。声明应用的函数“必须从ndarray输入中生成单个值”。它的实际含义似乎是“必须产生一个可以或可以转换为单个浮点的值”。如果您跟踪完整的异常回溯,它将引导您在algos.pyx
中找到此代码:
output = np.empty(n, dtype=float)
counts = roll_sum(np.isfinite(input).astype(float), win, minp)
bufarr = np.empty(win, dtype=float)
oldbuf = <float64_t*> bufarr.data
n = len(input)
for i from 0 <= i < int_min(win, n):
if counts[i] >= minp:
output[i] = func(input[int_max(i - win + 1, 0) : i + 1], *args,
**kwargs)
else:
output[i] = NaN
因此,它试图将polyfit
的输出分配给float-ndarray的单个元素,但失败了,因为polyfit的输出是一个无法转换为float的数组
这可以通过使输出
具有dtype对象来“修复”,但这会大大降低速度
我想你必须考虑<代码> RoLungIpAp/<代码>,只对返回单个浮点的函数可用。为了支持非标量输出,您必须滚动(har-har)您自己版本的
rolling\u apply
我想创建一个IIR过滤器类型的时间序列扩展。
例如:[1,2,3,4,5]窗口=2时应给出:[[1,2],[2,3],[3,4],[4,5]]
下面是我的解决方案,它基于一些糟糕的编码实践,但却完成了工作。
从rolling_apply()返回全局dict/数组的索引,并丢弃返回值。滚动应用返回时,dict中的解决方案已准备就绪
import pandas as pd
import numpy as np
dataDict = dict()
INDEX = 0
def windowFunc(w):
global INDEX
global dataDict
dataDict[INDEX] = np.copy(w)
INDEX = INDEX + 1
return INDEX
dd = pd.DataFrame([1,2,3,4,5,6,7,8,9,0])
dd2 = pd.rolling_apply(dd, window=2, func = windowFunc)
print(list(dataDict.values()))
我遇到了同样的问题,您只需将[0]添加到lambda函数:
coefs = pd.rolling_apply(my_ts, 21, lambda x: np.polyfit(range(len(x)), x, 3)[0])
它现在可以正常工作。由于rolling_apply已被弃用,Nissar的解决方案也可以与pd.rolling.apply方法一起使用:
coefs = my_ts.rolling(21).apply(lambda x: np.polyfit(range(len(x)), x, 3)[0])
这里特别重要的是Nissar使用range(len(x))来满足时间分量,这避免了无法使用rolling.apply和两列或两系列的lambda函数(因为x(时间)分量的一些占位符计数通常位于数据帧或另一系列的另一列中)
coefs = my_ts.rolling(21).apply(lambda x: np.polyfit(range(len(x)), x, 3)[0])