2016-04-03 51 views
3

我有数据数组,形状为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?

+0

适用于任何维度的解决方案:http://stackoverflow.com/questions/36269508/lets-make-a-reference-implementation-of-n-dimensional-pixel-binning-bucketing-f/36269734#36269734 –

+0

@ajcr我正在重新打开这个文件,因为重复的链接问题会涉及设置一个通用的ndarray情况的大量开销,这不需要解决这种情况。希望这听起来没问题。 – Divakar

回答

3

每个这些两轴的简单reshape分裂成两个各具有形状(5,20)再总结减少沿具有轴长度20,像这样 -

Z_new = Z.reshape(5,20,5,20).sum(axis=(1,3)) 

在功能上是相同的,但具有np.einsum潜在更快选项 -

Z_new = np.einsum('ijkl->ik',Z.reshape(5,20,5,20)) 

运行测试 -

In [18]: x = np.arange(100) 
    ...: y = np.arange(100) 
    ...: X, Y = np.meshgrid(x, y) 
    ...: Z = np.cos(X)*np.sin(Y) 
    ...: 

In [19]: %timeit Z.reshape(5,20,5,20).sum(axis=(1,3)) 
10000 loops, best of 3: 49.5 µs per loop 

In [20]: %timeit np.einsum('ijkl->ik',Z.reshape(5,20,5,20)) 
10000 loops, best of 3: 46.7 µs per loop 
0

您可以做以下操作。

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的解决方案快。

0

这样的问题对于像scipy.ndimage.measurements.sum这样的功能来说是非常好的候选,因为它允许“分组”和“标记”术语。你会得到你想要的东西,如:

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

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