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

时间:2014-07-31 11:04:30

标签: python arrays multidimensional-array filtering

我编写了一个邻域平滑滤波器,可以在用户提供的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

制作整个数组的副本,使得数组中位置[i,j]的值可以暂时变为NaN - 我不能只复制数组的移动窗口区域(这会更好)因为主数组的[i,j]不是移动窗口数组的[i,j]。

一个简单的“如果移动窗口中的位置值= =主数组中的值”条件将无效,因为如果值重复,这将失败。

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

测试该函数

有人有什么建议吗?

1 个答案:

答案 0 :(得分:1)

据我所见,这似乎与原始功能相同,无需复制。

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