我已经编写了一个邻域平滑过滤器,适用于用户提供的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]。
一个简单的"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