2 回答

TA貢獻(xiàn)1829條經(jīng)驗(yàn) 獲得超6個(gè)贊
這是一種方法 -
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部分帶入布爾構(gòu)造部分 -
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)
解釋
我們的想法是根據(jù)符號(hào)變化或當(dāng)我們遇到一系列 0 時(shí)將數(shù)組拆分為“島”,在這種情況下,我們希望將每個(gè)元素拆分為單獨(dú)的元素。通過(guò)拆分,可以將其視為列表的列表,如果這樣更容易理解的話?,F(xiàn)在,游戲是我們?nèi)绾潍@得這些分裂。我們需要表示這些島嶼的開始、停止索引的索引。如前所述,存在三種情況,符號(hào)從 變?yōu)?或-相反,或者 0 序列。
因此,布爾掩碼的結(jié)構(gòu)用于為這些索引提供一次性切片,以檢測(cè)從+到 的符號(hào)變化-,反之亦然np.diff(m1) | np.diff(m2)。最后一個(gè)m0[:-1]是針對(duì) 的序列0s。然后將這些指數(shù)輸入np.add.reduceat以獲得間隔求和。
樣本運(yùn)行 -
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])

TA貢獻(xiàn)1807條經(jīng)驗(yàn) 獲得超9個(gè)贊
這解決了問(wèn)題,但肯定有更聰明的方法來(lái)做到這一點(diǎn)
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
最后,數(shù)組的值為 [0, 0, 0, -2, 0, 5, 0, -1, 0, 2, -3]
添加回答
舉報(bào)