我正在尝试计算大数组的运行中位数,平均值和标准值。我知道如何计算运行平均值如下:
def running_mean(x, N):
cumsum = np.cumsum(np.insert(x, 0, 0))
return (cumsum[N:] - cumsum[:-N]) / float(N)
这非常有效。但我不太明白为什么(cumsum[N:] - cumsum[:-N]) / float(N)
可以给出平均值(我从其他人那里借来的)。
我试图添加另一个返回句来计算中位数,但它没有做我想要的。
return (cumsum[N:] - cumsum[:-N]) / float(N), np.median(cumsum[N:] - cumsum[:-N])
有没有人提供一些提示来解决这个问题?非常感谢你。
张华年答案 0 :(得分:5)
cumsum
该诀窍专门用于查找sum
或average
值,并且您认为不能仅仅为了获取median
和std
值而扩展它。在ufunc
数组上的滑动/运行窗口中执行通用1D
操作的一种方法是创建一系列基于1D滑动窗口的索引,堆叠为2D数组,然后应用{{ 1}}沿堆叠轴。要获取这些索引,您可以使用broadcasting
。
因此,对于执行运行平均值,它看起来像这样 -
ufunc
要运行idx = np.arange(N) + np.arange(len(x)-N+1)[:,None]
out = np.mean(x[idx],axis=1)
和median
,只需将np.mean
分别替换为np.median
和np.std
。
答案 1 :(得分:0)
让我介绍一个包装器来移动“任何东西”:
import numpy as np
def runningFoo(operation):
""" Make function that applies central running window operation
"""
assert hasattr(np, operation), f"numpy has no method '{operation}'"
method = getattr(np, operation)
assert callable(method), f"numpy.{operation} is not callable"
def closure(X, windowSize):
assert windowSize % 2 == 1, "window size must be odd"
assert windowSize <= len(X), "sequence must be longer than window"
# setup index matrix
half = windowSize // 2
row = np.arange(windowSize) - half
col = np.arange(len(X))
index = row + col[:, None]
# reflect boundaries
row, col = np.triu_indices(half)
upper = (row, half - 1 - col)
index[upper] = np.abs(index[upper]) % len(X)
lower = (len(X) - 1 - row, windowSize - 1 - upper[1])
index[lower] = (len(X) - 2 - index[lower]) % len(X)
return method(X[index], axis=1)
return closure
例如,如果您想跑步,可以致电runningFoo("mean")
。实际上,您可以在NumPy中调用任何适当的方法。例如,runningFoo("max")
将是形态学扩张操作,runningFoo("min")
将是形态学侵蚀:
runningStd = runningFoo("std")
runningStd(np.arange(10), windowSize=3)
确保窗口大小是奇数。另外,请注意边界点会被反映。
答案 2 :(得分:-1)
为了估计给定样本集的均值和标准偏差,存在增量算法(std,mean),它可以帮助您保持较低的计算负荷并进行在线估算。中位数的计算应用排序。你可以近似中位数。令x(t)为给定时间t的数据,m(t)为时间t的中值,m(t-1)为中值,e为小数,例如: e = 0.001比
如果m(t-1)m(t)= m(t-1)-e,如果m(t-1)> X(t)的
m(t)= m(t),否则
如果您对中位数m(0)有一个很好的初始猜测,那么效果很好。应根据您的数值范围和预期的样本量来选择e。例如。如果x = [-4 2 7.5 2],如果x = [1000,3153,-586,-29],e = 10,e = 0.05就会好。