Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/302.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 熊猫的滚动窗口多项式拟合_Python_Numpy_Pandas - Fatal编程技术网

Python 熊猫的滚动窗口多项式拟合

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 = '

我试图从应用于时间序列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 = '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])