在 python 中计算 运行 中位数的最短方法是什么?

What is the shortest way to calculate running median in python?

我需要计算 python 中的 运行 中位数。目前我是这样做的:

med_y = []
med_x = []
for i in numpy.arange(240, 380, 1):

    med_y.append(numpy.median(dy[(dx > i)*(dx < i+20)]))
    med_x.append(i + 10)

此处数据存储在 dx(x 坐标)和 dy(y 坐标)中,中位数接管 dy 并绘制反对 dx(必须移动 window/2) .假设 x 的均匀间距和 window 这里的大小是 20.

有没有更短的路?

例如,运行平均值可以这样做:

cs = numpy.cumsum(dy)
y_20 = (cs[20:] - cs[:-20])/20.0
x_20 = dx[10:-10]

站点包中的预定义运行 X 函数也可以。

写完问题后谷歌搜索显示了称为 medfilt 的信号处理函数,例如scipy.signal.medfilt 有两个输入参数:数字列表和 window 大小。

在以下情况下有效:

  • window尺码不齐
  • 与边缘的距离超过 (window+1)/2

它在边缘附近给出内部最小值 window/2。我猜是因为它原本是为了减少图像中的黑色错误像素而你希望边缘是黑色的。

例如:

from scipy.signal import medfilt 
values = [1,1,1,0,1,1,1,1,1,1,1,2,1,1,1,10,1,1,1,1,1,1,1,1,1,1,0,1]
print medfilt(values,7)

完美适用于值 [4:-4] 并为边缘提供 min(values[:4]) 和 min(values[-4:]) 。上面例子的输出是:

output = [0. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. 0.] 

这是最短的:

from scipy.ndimage import median_filter
values = [1,1,1,0,1,1,1,1,1,1,1,2,1,1,1,10,1,1,1,1,1,1,1,1,1,1,0,1]
print median_filter(values, 7, mode='mirror')

它在边缘正常工作(或者您可以选择它在边缘的工作方式)。

而任何一般的运行 X都是这样完成的(运行标准差为例):

import numpy
from scipy.ndimage.filters import generic_filter
values = numpy.array([0,1,2,3,4,5,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1]).astype('float')
print(generic_filter(values, numpy.std, size=7, mode='mirror'))

在上面,float 输入类型很重要。

有用的链接:

https://nickc1.github.io/python,/matlab/2016/05/17/Standard-Deviation-(Filters)-in-Matlab-and-Python.html

improving code efficiency: standard deviation on sliding windows