2015-09-26 49 views
3

我有一个应用程序,我需要在3D NumPy数组中的任意索引组求和。内置的NumPy数组求和例程对一个ndarray维度的所有索引进行求和。相反,我需要总结我的数组中的一个维度的索引范围,并返回一个新的数组。NumPy sumin沿无交集索引

例如,我们假设我有一个形状为(70,25,3)的ndarray。我希望总结沿着特定索引范围的第一个维度并返回一个新的3D数组。考虑从0:25, 25:5050:75的总和,这将返回形状为(3,25,3)的数组。

是否有一种简单的方法可以在NumPy数组的一维上执行“不相交的和”来产生这个结果?

+0

这些*范围*的范围是否相同? – Divakar

回答

8

您可以使用np.add.reduceat作为此问题的一般方法。即使范围不是全部相同的长度,这也是有效的。

综上所述切片0:2525:5050:75沿着轴线0,在通过索引[0, 25, 50]

np.add.reduceat(a, [0, 25, 50], axis=0) 

这种方法也可以用来总结非连续范围。例如,为了总结切片0:2537:4751:75,写:

np.add.reduceat(a, [0,25, 37,47, 51], axis=0)[::2] 

的另一种方法和总结了相同长度的范围是重塑数组,然后沿轴线总结。相当于上面的第一个例子:

a.reshape(3, a.shape[0]//3, a.shape[1], a.shape[2]).sum(axis=1) 
+0

如果范围是连续的,则不需要重复索引。即'[0,25,50]'在这种情况下会做同样的工作。 – Jaime

+0

@Jaime:哦!感谢您的改进 - 我会更新答案。 –

+0

非常感谢您的解决方案,它的工作原理与我所期望的完全相同! – wbinventor

1

您可以使用np.split分裂您的数组,然后使用np.sum来总结您的项目沿着第二轴:

np.sum(np.split(my_array,3),axis=1) 

演示:

>>> a=np.arange(270).reshape(30,3,3) 
>>> np.sum(np.split(a,3),axis=1) 
array([[[ 405, 415, 425], 
     [ 435, 445, 455], 
     [ 465, 475, 485]], 

     [[1305, 1315, 1325], 
     [1335, 1345, 1355], 
     [1365, 1375, 1385]], 

     [[2205, 2215, 2225], 
     [2235, 2245, 2255], 
     [2265, 2275, 2285]]]) 

还要注意的是,如果你有一个不同的切片长度你可以通过你的片尾np.split功能:

>>> new=np.sum(np.split(a,[10,20,]),axis=1) 
>>> new 
array([[[ 405, 415, 425], 
     [ 435, 445, 455], 
     [ 465, 475, 485]], 

     [[1305, 1315, 1325], 
     [1335, 1345, 1355], 
     [1365, 1375, 1385]], 

     [[2205, 2215, 2225], 
     [2235, 2245, 2255], 
     [2265, 2275, 2285]]]) 
+0

'np.split'''把一个任意索引数组作为参数而不是整数(对于偶数分割) - 你可以使它适用于任意分割*吗? – wwii

+0

@wwii的确,更新! – Kasramvd

+0

@Kasramvd:我认为@ wwii的观点是,在这里使用'split'方法时,范围都必须是相同的长度。如果我们想要沿着一个轴的不同长度的范围,例如'np.split(a,[10,15,30])'中给出的那些长度,我们不能按照这个答案所示的方式对它们进行求和。 –

1

只需对每个部分进行求和并使用结果创建一个新数组。

import numpy as np 
i1, i2 = (2,7) 

a = np.ones((10,5,3)) 
b = np.sum(a[0:i1,...], 0) 
c = np.sum(a[i1:i2,...], 0) 
d = np.sum(a[i2:,...], 0) 

g = np.array([b,c,d]) 

>>> g.shape 
(3, 5, 3) 
>>> g 
array([[[ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.], 
     [ 2., 2., 2.]], 

     [[ 5., 5., 5.], 
     [ 5., 5., 5.], 
     [ 5., 5., 5.], 
     [ 5., 5., 5.], 
     [ 5., 5., 5.]], 

     [[ 3., 3., 3.], 
     [ 3., 3., 3.], 
     [ 3., 3., 3.], 
     [ 3., 3., 3.], 
     [ 3., 3., 3.]]]) 
>>>