2015-09-26 50 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.]]]) 
>>>