簡體   English   中英

總結numpy數組中的非零元素

[英]Summing up non-zero elements in numpy array

我想總結一個數組(1-d)的非零元素,但分別對正整數和負整數(它們只能是一和二)進行總結,並在它們所在的位置顯示零。

數組示例:

array = np.array([0, 0, 0, -1, -1, 0, 1, 2, 1, 1, 0, -1, 0, 1, 1, -1, -2])

輸出:

array([0, 0, 0, -2, 0, 5, 0, -1, 0, 2, -3])

我認為我的問題是我不知道如何將數組中的正值和負值序列分開。

這是一種方法 -

def sum_by_signs(a):
    m1 = a<0
    m2 = a>0
    m0 = a==0 # or ~m1 & ~m2
    p = np.flatnonzero(m0[:-1] | np.diff(m1) | np.diff(m2))+1
    return np.add.reduceat(a, np.r_[0,p])

或者將np.r_[0部分帶np.r_[0構造部分 -

def sum_by_signs_v2(a):
    m1 = a<0
    m2 = a>0
    m0 = a==0 # or ~m1 & ~m2
    p = np.flatnonzero(np.r_[True, m0[:-1] | np.diff(m1) | np.diff(m2)])
    return np.add.reduceat(a, p)

解釋

我們開始考慮根據符號變化或當我們遇到一系列 0 時將數組拆分為“孤島”,在這種情況下,我們希望將每個元素拆分為一個單獨的元素。 通過拆分,將其視為列表列表,如果這樣更容易理解的話。 現在,游戲是我們如何獲得這些分裂。 我們需要表示這些島的開始、停止索引的索引。 如前所述,存在三種情況,符號從+變為-或反之亦然或序列為 0。

因此,布爾掩碼的結構用於為這些索引提供一次性切片,以檢測從+-符號變化,反之亦然,結合np.diff(m1) | np.diff(m2) np.diff(m1) | np.diff(m2) m0[:-1]最后一個是0s序列。 然后將這些索引輸入np.add.reduceat以獲得間隔求和。

樣品運行 -

In [208]: a
Out[208]: array([ 0,  0,  0, -1, -1,  0,  1,  2,  1,  1,  0, -1,  0,  1,  1, -1, -2])

In [209]: sum_by_signs(a)
Out[209]: array([ 0,  0,  0, -2,  0,  5,  0, -1,  0,  2, -3])

In [211]: a
Out[211]: array([ 1,  2,  0, -1, -1,  0,  1,  2,  1,  1,  0, -1,  0,  1,  1, -1, -2])

In [212]: sum_by_signs(a)
Out[212]: array([ 3,  0, -2,  0,  5,  0, -1,  0,  2, -3])

In [214]: a
Out[214]: 
array([ 1,  2,  0, -1, -1,  0,  1,  2,  1,  1,  0, -1,  0,  1,  1, -1, -2,
        0])

In [215]: sum_by_signs(a)
Out[215]: array([ 3,  0, -2,  0,  5,  0, -1,  0,  2, -3,  0])

這解決了問題,但肯定有更聰明的方法來做到這一點

array = [0, 0, 0, -1, -1, 0, 1, 2, 1, 1, 0, -1, 0, 1, 1, -1, -2]

switch = 0
while switch == 0:
    for i in range(len(array)):
        try:
            array[i+1]
            if array[i] > 0 and array[i+1] > 0: 
                array[i] += array[i + 1]
                array.pop(i + 1)
                break
            elif array[i] < 0 and array[i+1] < 0:   
                array[i] += array[i + 1]
                array.pop(i + 1)
                break
        except:
            switch = 1
            break

最后,數組的值為 [0, 0, 0, -2, 0, 5, 0, -1, 0, 2, -3]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM