问题描述
我有一个平均数量的 3D 场。现在我正在寻找一种pythonic方法来恢复平均以获得每个时间戳的瞬时值。注:平均是从整个期间开始计算的。这就像滚动平均值,窗口大小适应要平均的值的索引。
为了更好的说明,我举了一个一维的例子:
import numpy as np
input_array = np.array([
[0. ],[0.5 ],[1. ],[1.5 ],[2. ],[2.5 ],[3. ],[3.25 ],[3.333333],[3.3 ],[3.181818],[2.769231]
])
exp_result = de_average(input_array)
预期结果 exp_result
应如下所示:
exp_result= np.array([
[0],[1],[2],[3],[4],[5],[6],[0]])
解决方法
这样的事情应该可以工作。您的问题与反向累积和问题非常相关,因此我使用了给定 here 的部分解决方案。
from itertools import tee
def pairwise(iterable):
"s -> (s0,s1),(s1,s2),(s2,s3),..."
a,b = tee(iterable)
next(b,None)
return zip(a,b)
def inverse_cumsum(cumulative):
""" Inverse an array obtained by cumulative sum
[1,3,6,10,15,21,28,36,45] -> [1,2,4,5,7,8,9]
"""
yield cumulative[0]
for a,b in pairwise(cumulative):
yield b-a
def inverse_average(a,decimals=1):
""" Inverse an array averaged (where each entry i is the average up to i) """
deav = inverse_cumsum([a * (i + 1) for i,a in enumerate(a)])
return np.array(list(deav)).round(decimals)
inverse_average(input_array)
,
对于一维 numpy 数组:
import numpy as np
def de_average(input_array):
timesteps = np.arange(1,input_array.shape[0] + 1).resize(-1,1)
_sum = timesteps.dot(input_array.T).diagonal()
original = np.empty(input_array.shape,dtype=int)
original[0,0] = _sum[0]
original[1:,0] = _sum[1:] - _sum[:-1]
return original
正如评论中提到的,这不适用于高维数组。
对于 2-D 和 3-D numpy 数组,请尝试:
import numpy as np
# de-averages along axis 0
def de_average(input_array):
_sum = np.apply_along_axis(
lambda x:x*range(1,input_array.shape[0]+1),input_array
)
original = np.array(input_array)
original[1:] = _sum[1:] - _sum[:-1]
return original.astype(int)