数组大小为 NbyN 的 window 中元素的平均值

average of elements within a window of size NbyN of an array

objective是求window/kernal内元素的平均值。

示例案例:

x = np.array([[1,2,3,4],[1,2,3,4],[1,2,3,4],[1,2,3,np.nan]])
window size - 2 by 2
ex: overlying window on x  sum(x[0,0]+x[0,1]+x[1,0]+x[1,1])/4 = 1.5
>> y
array([[ 1.5  ,  3.5  ],
       [ 1.5  ,  3.333]])

尝试过的方法:(I) 通过硬编码为 window 大小为 2,2

的循环
S,T = x.shape
viArray_at_LR = np.empty([S/2,T/2])
viArray_at_LR[:] = np.nan
rowIncre = 0
for s in range(0,S-1,2):
    colIncre = 0
    for t in range(0,T-1,2):
        try:
            viArray_at_LR[rowIncre,colIncre] = np.nanmean([x[s,t],x[s,t+1],x[s+1,t],x[s+1,t+1]])
        except KeyError:
            print "nan values at ",s,t
        colIncre = colIncre + 1
    rowIncre = rowIncre + 1

II) 使用kernals,这个returns与kernal jump 相同大小的数组是一个元素。

import scipy.ndimage as ndimage
out = ndimage.generic_filter(array, np.nanmean, footprint=kernel, mode='wrap')

我希望输出 array.size 为 input_arr.size/window.size

我正在寻找一种通用方法,可以在不使用循环的情况下针对任何 window 大小 (N,N) 完成此操作

除非您使用 CUDA 或其他东西,否则您将使用循环。此外,任何 window 大小可能不是一个好主意,因为它对边缘有未定义的行为。如果您使用 window 大小,它是数组大小 N 的除数,您可以执行以下操作:

def coarsegrain(x,w=2):
    N = len(x)
    M = N//w
    y = zeros((M,M))
    for i in range(M):
        for j in range(M):
            y[i,j] = np.nanmean(x[w*i:w*i+w,w*j:w*j+w])
    return y

如果你想环绕索引,你可以像这样使用 "fancy" 索引:

def coarsegrain_wrap(x,w=2):
    N = len(x)
    M = int(ceil(N/w))
    y = zeros((M,M))
    for i in range(M):
        for j in range(M):
            y[i,j] = np.nanmean(numpy.take(x,[list(range(w*i,(w*i+w))),list(range(w*j,(w*j+w)))],mode="wrap"))
    return y

一般来说,我强烈建议坚持使用 window 大小,它们是数组大小的整数除数。其他任何东西都会产生边界伪影。但是,如果阵列足够大,伪影就不是什么大问题,可能会被修剪掉。仅在 Python3.

中才需要在 list 中包装 range