Pandas:在数据框中创建一个新列,它是滚动窗口的一个功能

Tho*_*ips 1 python user-defined-functions dataframe pandas

我有一个数据框,可以使用计算一个滚动10周期的新列pandas.stats.moments.rolling_mean(ExistingColumn, 10, min_periods=10).如果可用的时间少于10个,我会得到一个NaN.我可以为滚动中位数做同样的事情.完善.

我现在想要计算N个周期的其他滚动函数,但是在我的生活中不能弄清楚如何使用Pandas的用户定义函数.特别是,我想计算一个滚动的10点Hodges Lehman Mean,其定义如下:

def hodgesLehmanMean(x): 
    return 0.5 * statistics.median(x[i] + x[j] for i in range(len(x)) for j in range(i+1,len(x)))
Run Code Online (Sandbox Code Playgroud)

如何将其转换为可应用于Pandas数据帧的滚动函数,如果传递少于10个周期,则返回NaN?我是一个熊猫新手,所以我特别感谢一个简单的解释和一个例子.

unu*_*tbu 5

你可以使用pandas.rolling_apply:

import numpy as np
def hodgesLehmanMean(x): 
    return 0.5 * np.median([x[i] + x[j] 
                           for i in range(len(x)) 
                           for j in range(i+1,len(x))])

df = pd.DataFrame({'foo': np.arange(20, dtype='float')})
df['bar'] = pd.rolling_apply(df['foo'], 10, hodgesLehmanMean)
print(df)
Run Code Online (Sandbox Code Playgroud)

产量

    foo   bar
0     0   NaN
1     1   NaN
2     2   NaN
3     3   NaN
4     4   NaN
5     5   NaN
6     6   NaN
7     7   NaN
8     8   NaN
9     9   4.5
10   10   5.5
11   11   6.5
12   12   7.5
13   13   8.5
14   14   9.5
15   15  10.5
16   16  11.5
17   17  12.5
18   18  13.5
19   19  14.5
Run Code Online (Sandbox Code Playgroud)

更快的版本hodgesLehmanMean是:

def hodgesLehmanMean_alt(x): 
    m = np.add.outer(x,x)
    ind = np.tril_indices(len(x), -1)
    return 0.5 * np.median(m[ind])
Run Code Online (Sandbox Code Playgroud)

这是一个完整性检查,显示hodgesLehmanMean_alt返回与hodgesLehmanMean1000个长度为100的随机数组相同的值:

In [68]: m = np.random.random((1000, 100))

In [69]: all(hodgesLehmanMean(x) == hodgesLehmanMean_alt(x) for x in m)
Out[69]: True
Run Code Online (Sandbox Code Playgroud)

这是一个基准显示hodgesLehmanMean_alt速度大约快8倍:

In [80]: x = np.random.random(5000)

In [81]: %timeit hodgesLehmanMean(x)
1 loops, best of 3: 3.99 s per loop

In [82]: %timeit hodgesLehmanMean_alt(x)
1 loops, best of 3: 463 ms per loop
Run Code Online (Sandbox Code Playgroud)