Python:移动窗口数组的访问索引,该索引匹配正在循环的数组的当前位置

Python:移动窗口数组的访问索引,该索引匹配正在循环的数组的当前位置,python,arrays,multidimensional-array,filtering,Python,Arrays,Multidimensional Array,Filtering,我已经编写了一个邻域平滑过滤器,它可以在用户提供的2D数组上工作-它可以按原样工作,但它可以更快/更少地浪费内存,因为目前每次循环运行时我都复制整个输入数组。当传入大型阵列时,这将证明是一个真正的问题 过滤器定义为: import numpy as np import os def conservative_smooth(array2D, kernel_size = 3): stepsize = 1 if(kernel_size

我已经编写了一个邻域平滑过滤器,它可以在用户提供的2D数组上工作-它可以按原样工作,但它可以更快/更少地浪费内存,因为目前每次循环运行时我都复制整个输入数组。当传入大型阵列时,这将证明是一个真正的问题

过滤器定义为:

    import numpy as np
    import os

    def conservative_smooth(array2D, kernel_size = 3):

        stepsize = 1    
        if(kernel_size % 2 != 0 and kernel_size >= 3):
            window = np.ones([kernel_size,kernel_size])
        elif(kernel_size % 2 == 0 or kernel_size < 3):
            print "kernel is even - it needs to be odd and at least of a value of 3"
            os._exit(1)

        nxwind, nywind = array2D.shape

        for i in range(0, nxwind, stepsize):
            for j in range(0, nywind, stepsize):

            # CALCULATE MAX AND MIN RANGES OF ROWS AND COLS THAT CAN BE ACCESSED 
            # BY THE WINDOW
            imin=max(0,i-((kernel_size-1)/2)) 
            imax=min(nxwind-1,i+((kernel_size-1)/2))+1
            jmin=max(0,j-((kernel_size-1)/2))
            jmax=min(nywind-1,j+((kernel_size-1)/2))+1

            # THIS IS THE MOST INEFFICIENT PART OF THE CODE
            array2D_temp = array2D.copy() 
            array2D_temp[i,j] = np.nan

            data_wind=array2D_temp[imin:imax,jmin:jmax]

            centre_value = array2D[i,j]
            max_value = np.nanmax(data_wind) 
            min_value = np.nanmin(data_wind) 

            if(centre_value > max_value):
                centre_value = max_value
            elif(centre_value < min_value):
                centre_value = min_value
            else:
                centre_value = centre_value

            ## Append new centre value to output array
            array2D[i,j] = centre_value         

        return array2D
将numpy导入为np
导入操作系统
def保守_平滑(阵列2d,内核_大小=3):
步长=1
如果(内核大小%2!=0,内核大小>=3):
window=np.one([内核大小,内核大小])
elif(内核大小%2==0或内核大小<3):
print“内核是偶数-它必须是奇数,并且至少值为3”
操作系统退出(1)
nxwind,nywind=array2D.shape
对于范围内的i(0,nxwind,步长):
对于范围内的j(0,nywind,步长):
#计算可访问的行和列的最大和最小范围
#靠窗
imin=max(0,i-((内核大小-1)/2))
imax=min(nxwind-1,i+((内核大小-1)/2))+1
jmin=max(0,j-((内核大小-1)/2))
jmax=min(nywind-1,j+((内核大小-1)/2))+1
#这是代码中最低效的部分
array2D_temp=array2D.copy()
阵列温度[i,j]=np.nan
数据风=阵列温度[imin:imax,jmin:jmax]
中心值=阵列2d[i,j]
最大值=np.nanmax(数据风)
最小值=np.nanmin(数据风)
如果(中心值>最大值):
中心值=最大值
elif(中心值<最小值):
中心值=最小值
其他:
中心值=中心值
##将新的中心值附加到输出数组
阵列2d[i,j]=中心值
返回阵列2d
制作整个数组的副本,以便数组中位置[i,j]处的值可以临时设置为NaN-我不能只复制数组的移动窗口区域(这会更好),因为主数组的[i,j]不会是移动窗口数组的[i,j]

简单的“if value at position in moving window==value in main array”条件也不起作用,因为如果值重复,则该条件将失败

我一直在使用一个简单的随机10x10数组(
a=np.random.rand(10,10)
)测试该函数


有人有什么建议吗?

据我所知,这似乎和您原来的功能一样,不需要复制

def conservative_smooth(array2D, kernel_size = 3):
    stepsize = 1    
    if(kernel_size % 2 != 0 and kernel_size >= 3):
        window = np.ones([kernel_size,kernel_size])
    elif(kernel_size % 2 == 0 or kernel_size < 3):
        print "kernel is even - it needs to be odd and at least of a value of 3"
        os._exit(1)
    nxwind, nywind = array2D.shape
    for i in range(0, nxwind, stepsize):
        for j in range(0, nywind, stepsize):
            # CALCULATE MAX AND MIN RANGES OF ROWS AND COLS THAT CAN BE ACCESSED 
            # BY THE WINDOW
            imin=max(0,i-((kernel_size-1)/2)) 
            imax=min(nxwind-1,i+((kernel_size-1)/2))+1
            jmin=max(0,j-((kernel_size-1)/2))
            jmax=min(nywind-1,j+((kernel_size-1)/2))+1
            centre_value = array2D[i,j]
            array2D[i,j] = np.nan
            max_value = np.nanmax(array2D[imin:imax,jmin:jmax]) 
            min_value = np.nanmin(array2D[imin:imax,jmin:jmax]) 
            if(centre_value > max_value):
                centre_value = max_value
            elif(centre_value < min_value):
                centre_value = min_value
            else:
                centre_value = centre_value
            ## Append new centre value to output array
            array2D[i,j] = centre_value      
    return array2D
def conservative_smooth(阵列2d,内核大小=3):
步长=1
如果(内核大小%2!=0,内核大小>=3):
window=np.one([内核大小,内核大小])
elif(内核大小%2==0或内核大小<3):
print“内核是偶数-它必须是奇数,并且至少值为3”
操作系统退出(1)
nxwind,nywind=array2D.shape
对于范围内的i(0,nxwind,步长):
对于范围内的j(0,nywind,步长):
#计算可访问的行和列的最大和最小范围
#靠窗
imin=max(0,i-((内核大小-1)/2))
imax=min(nxwind-1,i+((内核大小-1)/2))+1
jmin=max(0,j-((内核大小-1)/2))
jmax=min(nywind-1,j+((内核大小-1)/2))+1
中心值=阵列2d[i,j]
array2D[i,j]=np.nan
max_value=np.nanmax(array2D[imin:imax,jmin:jmax])
min_value=np.nanmin(array2D[imin:imax,jmin:jmax])
如果(中心值>最大值):
中心值=最大值
elif(中心值<最小值):
中心值=最小值
其他:
中心值=中心值
##将新的中心值附加到输出数组
阵列2d[i,j]=中心值
返回阵列2d

您不是总是将内核的中心设置为
nan
?它与
i,j
不同,但确实很容易找到?@jornsharpe由于边界的原因,内核并不总是相同的维度(例如3x3)-例如,在左上角,内核,即使设置为3x3,实际上也只有2x2。我从不跳出数组。我仍然认为为那些边缘(ha!)情况编写异常比继续复制整个数组要好,而对于所有的全尺寸样本来说,这是微不足道的。