我有一个数组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
上执行此操作,我想优化时间,所以我想避免循环或类似。并且......我不在乎边缘的结果。
我已经尝试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]
的,这显然不是正确的答案。 任何想法都是受欢迎的。
答案 0 :(得分:1)
正在使用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)
来计算
答案 1 :(得分:0)
我在pandas中制作一个长度为5的滚动中心窗口,并将中值函数应用于窗口的值,中间的一个被遮盖:
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