用最近邻居的中值替换列表中的(每个)元素

Replace (every) element in a list by the median of the nearest neighbors

我有一个数组 A,说:

import numpy as np
A = np.array([1,2,3,4,5,6,7,8])

我希望创建一个新数组 B,方法是将 A 中的每个元素替换为其四个最近邻元素的中值, 不考虑 计算给定位置的值...例如:

B[2] = np.median([A[0], A[1], A[3], A[4]]) (=3) 

问题是我需要在一个巨大的 A 上执行此操作并且我想优化时间,所以我想避免 for 循环或类似的。而且...我不关心边缘的结果。

我已经尝试过 scipy.ndimage.filters.median_filter 但它没有产生所需的输出:

import scipy.ndimage
B = scipy.ndimage.filters.median_filter(A,footprint=[1,1,0,1,1],mode='wrap')

产生 B=[7,4,4,5,6,7,6,6],这显然不是正确答案。 欢迎任何想法。

可能会使用 np.roll 来移动数组中的数字,例如:

A_1 = np.roll(A,1)
# output: array([8, 1, 2, 3, 4, 5, 6, 7])

然后按 -2、-1 和 2 滚动:

A_2 = np.roll(A,2)
A_m1 = np.roll(A,-1)
A_m2 = np.roll(A,-2)

现在您只需要对 4 个数组求和,对于每个索引,其中一个有 4 个邻居:

B = (A_1 + A_2 + A_m1 + A_m2)/4.

正如你所说的你不关心边缘,我认为它适合你!

编辑:我想我是在关注混合均值和中位数的滚动想法,中位数可以通过 B = np.median([A_1,A_2,A_m1,A_m2],axis=0)

计算

我将在 pandas 中制作长度为 5 的滚动中央 window,并将中值函数应用于 window 的值,中间的值被屏蔽掉:

import numpy as np
A = np.array([1,2,3,4,5,6,7,8])

mask = np.array(np.ones(5), bool)
mask[5//2] = False

import pandas as pd
df = pd.DataFrame(A)

r5 = df.rolling(5, center=True)

result = r5.apply(lambda x: np.median(x[mask]))

result
     0
0  NaN
1  NaN
2  3.0
3  4.0
4  5.0
5  6.0
6  NaN
7  NaN