如何平均维持其形状的3D矩阵切片

时间:2017-10-19 09:59:02

标签: python matrix raster

我得到了这个有效的代码片段:

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()

程序对输入矩阵(光栅图像)的3x3个切片进行平均(聚合),并设置一个新的维护原始矩阵的维数。

现在我觉得必须有一种更简单的方法来实现这一目标。 有人知道如何以更加pythonic的方式获得相同的结果吗?

谢谢!

3 个答案:

答案 0 :(得分:1)

据我所知,没有更容易或更快的方法来执行块方向平均。你的代码可能看起来很大,但大部分只是编写数组并调整大小或绘制内容。你的主要功能是一个位置很好的while - 循环,并且你将平均值留给numpy,它已经是一个快捷方式,应该可以快速运行。

我认为没有任何理由在不失去可读性的情况下进一步缩短这一点。

答案 1 :(得分:1)

如果你只是想让它看起来更短,而且更像是pythonic&#34;但不太可读,请为此:

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和质量检查(第一维和第二维可以除以大小等)来建立一个函数/方法。

答案 2 :(得分: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.]]])