2017-10-19 105 views
1

我得到這個工作的代碼片段:如何平均一個3D矩陣的片保持其形狀

import numpy as np 
from matplotlib import pyplot as plt 

in_raster = np.random.randn(36, 3, 2151) 
matrix = np.reshape(in_raster, [(np.shape(in_raster)[0] * np.shape(in_raster)[1]), np.shape(in_raster)[2]]) 
# reshaping the matrix to prepare loop 
out_raster = np.empty([np.shape(in_raster)[0]/3, np.shape(in_raster)[1]/3, np.shape(in_raster)[2]]) 
# creating empty output matrix 

i = 0 
j = 0 
while i <= len(in_raster)-9 or j < len(out_raster): 
    if i % 9 == 0: 
     avg_in_raster = np.nanmean(matrix[i:i+9, :], axis=0) 
     out_raster[j] = avg_in_raster 
    i += 9 
    j += 1 
out_raster = np.reshape(out_raster, [np.shape(out_raster)[0], np.shape(in_raster)[1]/3, np.shape(in_raster)[2]]) 

# plot example 
low = 0 
high = 50 

for row in range(0, 3): 
    for col in range(np.shape(in_raster)[1]): 
     plt.plot(range(low,high), (in_raster[row, col, low:high])) 
plt.plot(range(low,high), (out_raster[0,0,low:high]), 'k') 
plt.show() 

程序平均(聚集)輸入矩陣的3×3片(光柵圖像),並建立了一個新的一個維護原始矩陣的維度。

現在我覺得必須有一種更簡單的方法來實現這一點。 有人有一個想法如何以更pythonic的方式獲得相同的結果?

謝謝!

回答

1

據我所知,沒有更容易或更快的方法來執行逐段平均。你的代碼可能看起來很大,但大部分只是數組的準備和調整或繪製東西。你的主要功能是一個放置良好的while -loop,並且你自己的平均值爲numpy,這已經是一個快捷方式,應該快速運行。

我沒有看到任何理由進一步縮短這一點,而不會失去可讀性。

1

如果你只是想使它看起來更短,「更Python」,但可讀性變差,去這樣的:

import numpy as np 
from matplotlib import pyplot as plt 

in_raster = np.random.randn(36, 3, 2151) 

size=3 

matrix=np.array([in_raster[:,:,i].flatten() for i in np.arange(in_raster.shape[2])]).transpose() 

out_raster2 = np.array([np.nanmean(matrix[i:i+size**2, :], axis=0) for i in np.arange(len(matrix)) if not i%size**2]).reshape(np.shape(in_raster)[0]/size, np.shape(in_raster)[1]/size, np.shape(in_raster)[2]) 

# plot example 
low = 0 
high = 50 

for row in range(0, 3): 
    for col in range(np.shape(in_raster)[1]): 
     plt.plot(range(low,high), (in_raster[row, col, low:high])) 
plt.plot(range(low,high), (out_raster2[0,0,low:high]), 'k') 
plt.show() 

#plt.plot((out_raster2-out_raster)[0,0,low:high]) # should be all 0s 
#plt.show() 

而且你可以把一個函數/方法與屬性size = 3和質量檢查(第一維和第二維可以按大小等進行劃分)。

1

您應該可以通過在一個方向上擴展形狀並在該維度上取平均值來完成此操作。像這樣:

out_raster1 = np.nanmean(in_raster.reshape(36*3//9, -1, 2151), axis=1).reshape(12, 1, -1) 

檢查一致性,

>>> out_raster1-out_raster 
array([[[ 0., 0., 0., ..., 0., 0., 0.]], 

    [[ 0., 0., 0., ..., 0., 0., 0.]], 

    [[ 0., 0., 0., ..., 0., 0., 0.]], 

    ..., 
    [[ 0., 0., 0., ..., 0., 0., 0.]], 

    [[ 0., 0., 0., ..., 0., 0., 0.]], 

    [[ 0., 0., 0., ..., 0., 0., 0.]]])