2017-08-16 2 views
1

matlabには、各エントリにn個の最も近いエントリの平均値を取る関数があります。は、Pythonでmatlab平均フィルタを作成します

x=np.array([[0.1,0.8,.2], 
      [0.5,0.2,np.nan], 
      [0.7,0.2,0.9], 
      [0.4,0.7,1], 
      [np.nan,0.14,1]]) 

は、MathWorks社のMATLABでの平均フィルタを作成します。

x=[[0.1,0.8,.2], 
    [0.5,0.2,nan], 
    [0.7,0.2,0.9], 
    [0.4,0.7,1], 
    [nan,0.14,1]] 

fspecial('average',[3,3]) 
filter2(ave1,x) 

[[ 0.17777778   nan   nan] 
[ 0.27777778   nan   nan] 
[ 0.3    nan   nan] 
[  nan   nan 0.43777778] 
[  nan   nan 0.31555556]] 

は私のpythonにこれを変換したいです。 uniform filter と:私はこれを発見した skimage.filters.rank.mean

をしかし、結果は、MATLABと同じではありません。均一フィルタ:

x=np.array([[0.1,0.8,.2], 
      [0.5,0.2,np.nan], 
      [0.7,0.2,0.9], 
      [0.4,0.7,1], 
      [np.nan,0.14,1]]) 

print(uniform_filter(x, size=3, mode='constant')) 

[[ 0.17777778   nan   nan] 
[ 0.27777778   nan   nan] 
[ 0.3    nan   nan] 
[  nan   nan   nan] 
[  nan   nan   nan]] 

skimageフィルタ:

from skimage.filters.rank import mean 
from skimage.morphology import square 
from skimage import img_as_float 
x=np.array([[0.1,0.8,.2], 
     [0.5,0.2,np.nan], 
     [0.7,0.2,0.9], 
     [0.4,0.7,1], 
     [np.nan,0.14,1]]) 

print(mean(x, square(3))) 

[[102 76 76] 
[106 102 97] 
[114 130 127] 
[ 90 142 167] 
[ 79 137 181]] 

print(img_as_float(mean(x, square(3)))) 

[[ 0.4   0.29803922 0.29803922] 
[ 0.41568627 0.4   0.38039216] 
[ 0.44705882 0.50980392 0.49803922] 
[ 0.35294118 0.55686275 0.65490196] 
[ 0.30980392 0.5372549 0.70980392]] 

は最終的に私はそれに自分自身を持っていますが、性能には成熟していないされています

x=np.array([[0.1,0.8,.2], 
      [0.5,0.2,np.nan], 
      [0.7,0.2,0.9], 
      [0.4,0.7,1], 
      [np.nan,0.14,1]]) 



Winsize=3 
adder=int(Winsize/2) 
result=np.zeros_like(x) 
nan_window_index=np.array([]) 
for i in range(x.shape[0]): 
    for j in range(x.shape[1]): 
     top_left_r= int(i-adder) 
     top_left_c= int(j-adder) 
     bottom_right_r=int(i+adder) 
     bottom_right_c=int(j+adder) 
     sum_list=np.array([]) 

     for r_counter in range(top_left_r, bottom_right_r+1): 
      if r_counter<0 or r_counter > x.shape[0]-1: 
       continue 
      for c_counter in range(top_left_c, bottom_right_c+1): 
       if c_counter<0 or c_counter > x.shape[1]-1: 
        continue 
       if not np.isnan(x[r_counter, c_counter]): 
        sum_list=np.append(sum_list, x[r_counter, c_counter]) 
       else: 
        nan_window_index=np.append(nan_window_index, [[r_counter, c_counter]]) 

     result[i,j]= np.sum(sum_list)/(Winsize*Winsize) 

nan_window_index=np.unique(nan_window_index.reshape(int(len(nan_window_index)/2),2), axis=0) 

for i,j in nan_window_index: 
    top_left_r= int(i-adder) 
    top_left_c= int(j-adder) 
    bottom_right_r=int(i+adder) 
    bottom_right_c=int(j+adder) 

    for r_counter in range(top_left_r, bottom_right_r+1): 
     if r_counter<0 or r_counter > x.shape[0]-1: 
      continue 
     for c_counter in range(top_left_c, bottom_right_c+1): 
      if c_counter<0 or c_counter > x.shape[1]-1: 
       continue 
      result[r_counter, c_counter]=np.nan 

print(result) 

と結果がMATLABと同じです。

[[ 0.17777778   nan   nan] 
[ 0.27777778   nan   nan] 
[ 0.3    nan   nan] 
[  nan   nan 0.43777778] 
[  nan   nan 0.31555556]] 

any suggestioパフォーマンス向上のためにn? (それは迅速であるかもしれないとして、または多分scipy.signal.convolve2d

答えて

3

あなたとしてscipy.signal.convolveを使用することができます。

import numpy as np 
# from scipy.signal import convolve 
from scipy.signal import convolve2d 

x=np.array([[0.1,0.8,.2], 
      [0.5,0.2,np.nan], 
      [0.7,0.2,0.9], 
      [0.4,0.7,1], 
      [np.nan,0.14,1]]) 

core = np.full((3,3),1/3**2) 

# convolve(x, core, mode='same') 
convolve2d(x, core, mode='same') 

均一な値を持つ畳み込みは、均一フィルタと同じです。これは自動的にマトリクスの外側のゼロを「仮定」しますが、それはあなたが求めているものと一致しているので、現在の設定でうまくいくことに注意してください。

関連する問題