如何使用 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()
我想在
yavg
中添加一列df
,其在给定索引值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
是所有可能的np.array
值的x0
;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
的所有值更快。