使用 numpy 将时间平均值恢复为即时值
Revert time averaged values to instant values with numpy
我有一个平均数量的 3D 场。现在我正在寻找一种 pythonic 方法来恢复平均以获得每个时间戳的瞬时值。注意:平均是从整个周期的开始进行的。它就像滚动平均值,window 大小适应要平均的值的索引。
为了更好地说明,我给出了一个一维示例:
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],
[3. ],
[2.769231]
])
exp_result = de_average(input_array)
预期结果 exp_result
应如下所示:
exp_result= np.array([
[0],
[1],
[2],
[3],
[4],
[5],
[6],
[5],
[4],
[3],
[2],
[1],
[0]])
像这样的东西应该有用。你的问题与反向 cumsum 问题非常相关,所以我使用了给定 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, 3, 4, 5, 6, 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),
0,
input_array
)
original = np.array(input_array)
original[1:] = _sum[1:] - _sum[:-1]
return original.astype(int)
我有一个平均数量的 3D 场。现在我正在寻找一种 pythonic 方法来恢复平均以获得每个时间戳的瞬时值。注意:平均是从整个周期的开始进行的。它就像滚动平均值,window 大小适应要平均的值的索引。
为了更好地说明,我给出了一个一维示例:
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],
[3. ],
[2.769231]
])
exp_result = de_average(input_array)
预期结果 exp_result
应如下所示:
exp_result= np.array([
[0],
[1],
[2],
[3],
[4],
[5],
[6],
[5],
[4],
[3],
[2],
[1],
[0]])
像这样的东西应该有用。你的问题与反向 cumsum 问题非常相关,所以我使用了给定 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, 3, 4, 5, 6, 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),
0,
input_array
)
original = np.array(input_array)
original[1:] = _sum[1:] - _sum[:-1]
return original.astype(int)