2017-09-08 43 views
1

我試圖找到一種方法來基於布爾指數基於數值求和,使用模函數來確定月開始/結束。求和Numpy布爾指數

months = np.arange(36) + 1 # +1 to denote months rather than index 
vals = np.ones(36) 
vals[12:24] = 2 
vals[24:36] = 3 

# closest try: 

vals.cumsum()[[months % 12 == 0]] # returns array([12, 36, 72]) 

# target result = array([12, 24, 36]) 

的vals.sum()函數只是總結了整個事情,但cumsum積累了整個事情,這並不完全符合我要找的。目標結果包括在上面 - 這是一種常用的電子表格彙總技術,通常使用SUMIF函數根據特定參數對值進行彙總。

有沒有簡單的方法來做到這一點?我確信有,我只是想念它,我已經花了一些時間來試圖得出這個數字 - 寧願不使用for循環。

謝謝。

回答

2

看來你需要np.add.reduceat

np.add.reduceat(vals, np.flatnonzero((months - 1) % 12 == 0)) 
# array([ 12., 24., 36.]) 

說明

months 
# array([ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 
#  18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 
#  35, 36]) 

1)。使用模找出的條件,其中的總和應(months - 1) % 12開始:

(months - 1) % 12 == 0 
# array([ True, False, False, False, False, False, False, False, False, 
#  False, False, False, True, False, False, False, False, False, 
#  False, False, False, False, False, False, True, False, False, 
#  False, False, False, False, False, False, False, False, False], dtype=bool) 

2)。 np.flatnonzero類似於np.where並給出了索引,所以在這裏,所述第一總和從0開始直到12(不含)等:

np.flatnonzero((months - 1) % 12 == 0) 
array([ 0, 12, 24]) 

3)。找出指標後,使用np.add.reduceat總結段:

np.add.reduceat(vals, [0, 12, 24]) 
# array([ 12., 24., 36.]) 

從本質上講,這相當於[sum(vals[0:12]), sum(vals[12:24]), sum(vals[24:])]併爲您提供所需的輸出。

+0

給你upvote,但我有不到15代表所以它不顯示。這工作。你介意解釋一下嗎?不知道減少是如何工作的,並沒有發現flatnonzero的明確解釋。 – user7038639

+0

當然更新說明... – Psidom

+0

很好的解釋,謝謝。你是否從幾個月減去1,因爲flatnonzero使用基於0的索引而不是我試圖使用的每月索引? – user7038639

1

np.sum(vals[np.where(months % 12 == 0)[0]])也許?

np.where用於選擇索引。