我在m*n matrix
中有一个numpy
。我想将我的矩阵划分为2 * 2块,然后用其块中元素的平均值替换每个元素。例如,考虑以下数组:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12],
[13, 14, 15, 16]
]
我想制作这个矩阵:
[
[3.5, 3.5, 5.5, 5.5]
[3.5, 3.5, 5.5, 5.5]
[11.5, 11.5, 13.5, 13.5]
[11.5, 11.5, 13.5, 13.5]
]
最有效的方法是什么?我应该使用for循环吗?
答案 0 :(得分:5)
一种方法是将这两个轴中的每一个重新分成另外两个轴并沿着这两个轴中的后一个找到mean
,给出平均值。我们将使用keepdims=True
保留尺寸,以便于稍后使用np.repeat
沿缩小的轴复制最终输出。
因此,一个实现将是 -
b = a.reshape(2,2,2,2).mean((1,3), keepdims=1)
out = np.repeat(np.repeat(b,(2),axis=(1)),(2), axis=3).reshape(4,4)
示例运行 -
In [17]: a
Out[17]:
array([[ 1, 2, 3, 4],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12],
[13, 14, 15, 16]])
In [18]: b = a.reshape(2,2,2,2).mean((1,3), keepdims=1)
In [19]: np.repeat(np.repeat(b,(2),axis=(1)),(2), axis=3).reshape(4,4)
Out[19]:
array([[ 3.5, 3.5, 5.5, 5.5],
[ 3.5, 3.5, 5.5, 5.5],
[ 11.5, 11.5, 13.5, 13.5],
[ 11.5, 11.5, 13.5, 13.5]])
通常说,解决方案看起来像这样 -
m,n = a.shape
p,q = (2,2) # Block size
b = a.reshape(m//p,p,n//q,q).mean((1,3), keepdims=1)
out = np.repeat(np.repeat(b,(p),axis=(1)),(q), axis=3).reshape(a.shape)
提升绩效
我们可以用基于初始化的部分替换该复制部分,如此 -
out = np.empty((m//p,p,n//q,q),dtype=float)
out[:] = b
out.shape = a.shape