如何计算数组块内的值的总和 [英] How to evaluate the sum of values within array blocks
问题描述
我有数据数组,形状为 100x100.我想把它分成5x5块,每个块有20x20个网格.我想要的每个块的值是其中所有值的总和.
I have data array, with shape 100x100. I want to divide it into 5x5 blocks, and each block has 20x20 grids. The value of each block I want is the sum of all values in it.
有没有更优雅的方式来完成它?
Is there a more elegant way to accomplish it?
x = np.arange(100)
y = np.arange(100)
X, Y = np.meshgrid(x, y)
Z = np.cos(X)*np.sin(Y)
Z_new = np.zeros((5, 5))
for i in range(5):
for j in range(5):
Z_new[i, j] = np.sum(Z[i*20:20+i*20, j*20:20+j*20])
这是基于索引的,如果基于x呢?
This is based on index, how if based on x?
x = np.linspace(0, 1, 100)
y = np.linspace(0, 1, 100)
X, Y = np.meshgrid(x, y)
Z = np.cos(X)*np.sin(Y)
x_new = np.linspace(0, 1, 15)
y_new = np.linspace(0, 1, 15)
Z_new?
推荐答案
Simply reshape
将这两个轴中的每一个分成两个形状 (5,20)
以形成 4D
数组,然后沿长度为 20
的轴求和,就像这样 -
Simply reshape
splitting each of those two axes into two each with shape (5,20)
to form a 4D
array and then sum reduce along the axes having the lengths 20
, like so -
Z_new = Z.reshape(5,20,5,20).sum(axis=(1,3))
功能相同,但使用 np.einsum
-
Functionally the same, but potentially faster option with np.einsum
-
Z_new = np.einsum('ijkl->ik',Z.reshape(5,20,5,20))
通用块大小
扩展到一般情况-
H,W = 5,5 # block-size
m,n = Z.shape
Z_new = Z.reshape(H,m//H,W,n//W).sum(axis=(1,3))
随着 einsum
变成 -
Z_new = np.einsum('ijkl->ik',Z.reshape(H,m//H,W,n//W))
要计算跨块的平均值/平均值,请使用 mean
而不是 sum
方法.
To compute average/mean across blocks, use mean
instead of sum
method.
通用块大小和缩减操作
扩展使用具有ufuncs
支持多个 axes
参数和 axis
用于减少,这将是 -
Extending to use reduction
operations that have ufuncs
supporting multiple axes
parameter with axis
for reductions, it would be -
def blockwise_reduction(a, height, width, reduction_func=np.sum):
m,n = a.shape
a4D = a.reshape(height,m//height,width,n//width)
return reduction_func(a4D,axis=(1,3))
因此,要解决我们的具体情况,将是:
Thus, to solve our specific case, it would be :
blockwise_reduction(Z, height=5, width=5)
对于逐块平均计算,它将是 -
and for a block-wise average computation, it would be -
blockwise_reduction(Z, height=5, width=5, reduction_func=np.mean)
这篇关于如何计算数组块内的值的总和的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!