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

Posted

技术标签:

【中文标题】Pandas:在数据框中创建一个新列,该列是滚动窗口的函数【英文标题】:Pandas: create a new column in a dataframe that is a function of a rolling window 【发布时间】:2015-01-16 18:31:55 【问题描述】:

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

我现在想计算 N 个周期的其他滚动函数,但不能 我的生活弄清楚如何在 Pandas 中使用用户定义的函数。在 特别是,我想计算一个滚动的 10 点霍奇斯雷曼平均值,即 定义如下:

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)))

我怎样才能把它变成一个可以应用于熊猫的滚动函数 如果传递给它的句点少于 10 个,则返回一个 NaN?我是一个 熊猫新手,所以我特别感谢一个简单的解释 一个例子。

【问题讨论】:

如果你查看documentation,你可以看到rolling_apply函数,它允许你以滚动方式应用任何函数。您的函数必须将“滚动窗口”内的数据作为参数。目前尚不清楚您的 hodgesLehmannMean 如何涉及窗口。 x 是什么?是窗口还是整个数据集? 【参考方案1】:

你可以使用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)

产量

    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

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])

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

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

In [69]: all(hodgesLehmanMean(x) == hodgesLehmanMean_alt(x) for x in m)
Out[69]: True

这是一个基准测试,显示 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

【讨论】:

x 是一个可迭代的(通常是一个列表)。您的解释和示例非常清楚。感谢磨坊。 很抱歉没有早点回复,但您的代码非常出色,因为它将例程加快了一个数量级。这次真是万分感谢。值得指出的是,Hodges Lehman 均值是一个非常有用的估计量,因为它在标准(高斯)情况下的效率非常高(95%),并且能够拒绝任意大的异常值,只要它们不超过 29%的点。简而言之,它为我们提供了平均值的大部分效率,具有很大的稳健性,并且没有中位数的缺点(例如锁定到静态中心值)。再次感谢。 这个答案与最新版本的熊猫已经过时 - 有更新它的计划吗?

以上是关于Pandas:在数据框中创建一个新列,该列是滚动窗口的函数的主要内容,如果未能解决你的问题,请参考以下文章

Pandas ValueError:值的长度与索引的长度不匹配 - 创建新列

从具有大量标签的 Pandas 数据框中创建 TensorFlow 数据集?

创建两行之和的新列,但每两行重复一次[重复]

如何向 pandas df 添加一个新列,该列从另一个数据帧返回同一组中更大的最小值

如何从 pandas groupby().sum() 的输出创建一个新列?

根据其他两列的值在 Pandas 中创建一个新列[重复]