计算非均匀域的移动平均



如何使用python + NumPy/SciPy计算滚动/移动平均线?讨论了观测值等间距时的情况,即索引等于整数范围。

在我的例子中,观察结果出现在任意时间,它们之间的间隔可以是任意浮点数。例如,

import pandas as pd
import numpy as np
df = pd.DataFrame({"y":np.random.uniform(size=100)}, index=np.random.uniform(size=100)).sort_index()

我想添加列yavgdf,其值在给定索引值x0处为

sum(df.y[x]*f(x0-x) for x in df.index) / sum(f(x0-x) for x in df.index)
对于给定函数f

,例如

def f(x):
return np.exp(-x*x)

我如何以最小的努力(最好是纯numpy)做到这一点?

我认为你可以这样做:

index_np_arr = df.index.values
weighted_sum = np.sum(df['y'].values[:, np.newaxis] * f(index_np_arr - index_np_arr[:, np.newaxis]), axis=0)
entire_sum = np.sum(f(index_np_arr[:, np.newaxis] - index_np_arr), axis=0)

df['yavg'] = pd.Series(weighted_sum/entire_sum, index=df.index)

基本上:

  • index_np_arr是所有可能的x0np.array;
  • entire_sum将通过重复向量n次得到索引中所有值的分母,其中n是索引的数量,然后减去每个x0。最后,它将总结这一切;
  • weighted_sum将做几乎相同的事情,除了在我们求和之前我们将乘以y向量。

完整代码:

import pandas as pd
import numpy as np
def f(x):
return np.exp(-x*x)
df = pd.DataFrame({"y":np.random.uniform(size=100)}, index=np.random.uniform(size=100)).sort_index()
index_np_arr = df.index.values
weighted_sum = np.sum(df['y'].values[:, np.newaxis] * f(index_np_arr - index_np_arr[:, np.newaxis]), axis=0)
entire_sum = np.sum(f(index_np_arr[:, np.newaxis] - index_np_arr), axis=0)

df['yavg'] = pd.Series(weighted_sum/entire_sum, index=df.index)

注意:这段代码确实有很高的内存使用量,因为您将创建形状为(n, n)的数组来使用矢量化函数计算总和,但可能比遍历x的所有值要快。

最新更新