Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/298.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何计算数组块中的值之和_Python_Numpy - Fatal编程技术网

Python 如何计算数组块中的值之和

Python 如何计算数组块中的值之和,python,numpy,Python,Numpy,我有数据阵列,形状为100x100。我想把它分成5x5个块,每个块有20x20个网格。我想要的每个块的值是其中所有值的总和 有没有更优雅的方式来完成它 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.s

我有数据阵列,形状为100x100。我想把它分成5x5个块,每个块有20x20个网格。我想要的每个块的值是其中所有值的总和

有没有更优雅的方式来完成它

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的呢

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?

简单地将这两个轴分成两个,每个轴的形状
(5,20)
形成一个
4D
数组,然后沿长度
20
的轴求和减少,如下所示-

Z_new = Z.reshape(5,20,5,20).sum(axis=(1,3))
功能相同,但可能更快-

通用块大小

扩展到一般情况-

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
方法

通用块大小和缩减操作

扩展到使用具有支持多个
参数的
减少
操作-

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))
blockwise_reduction(Z, height=5, width=5, reduction_func=np.mean)
因此,要解决我们的具体情况,应该是:

blockwise_reduction(Z, height=5, width=5)
对于块平均计算,它是-

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))
blockwise_reduction(Z, height=5, width=5, reduction_func=np.mean)
你可以做以下事情

t = np.eye(5).repeat(20, axis=1)
Z_new = t.dot(Z).dot(t.T)
这是正确的,因为
Z_new[i,j]=t[i,k]*Z[k,l]*t[j,l]


而且这似乎比Divakar的解决方案要快。

这样的问题是一个非常好的函数,因为它允许“分组”和“标记”术语。您将拥有您想要的东西,例如:

labels = [[20*(y//5) + x//5 for x in range(100)] for y in range(100)]
s = scipy.ndimage.measurements.sum(Z, labels, range(400))

(未测试,但这是想法)。

对于任何维度的解决方案:@ajcr我重新打开此问题,因为重复链接问题将涉及设置通用Ndaray案例的大量开销,而解决此类案例并不需要此开销。希望这听起来不错。可能是重复的