为了账号安全,请及时绑定邮箱和手机立即绑定

对 numpy 数组中的非零元素求和

对 numpy 数组中的非零元素求和

守着一只汪 2023-09-19 17:04:24
我想对数组(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])我认为我的问题是我不知道如何分离数组中正值和负值的序列。
查看完整描述

2 回答

?
肥皂起泡泡

TA贡献1829条经验 获得超6个赞

这是一种方法 -


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部分带入布尔构造部分 -


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)。最后一个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])


查看完整回答
反对 回复 2023-09-19
?
函数式编程

TA贡献1807条经验 获得超9个赞

这解决了问题,但肯定有更聪明的方法来做到这一点


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]


查看完整回答
反对 回复 2023-09-19
  • 2 回答
  • 0 关注
  • 84 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信