numpy 计算非均匀区域的移动平均值

mklgxw1f  于 2023-04-12  发布在  其他
关注(0)|答案(1)|浏览(129)

How to calculate rolling / moving average using 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)?

wqnecbli

wqnecbli1#

我想你可以这样做:

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是所有可能的x0值的np.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的所有值更快。

相关问题