Numpy:条件总和

新手上路,请多包涵

我有以下 numpy 数组:

 import numpy as np
arr = np.array([[1,2,3,4,2000],
                [5,6,7,8,2000],
                [9,0,1,2,2001],
                [3,4,5,6,2001],
                [7,8,9,0,2002],
                [1,2,3,4,2002],
                [5,6,7,8,2003],
                [9,0,1,2,2003]
              ])

我理解 np.sum(arr, axis=0) 提供结果:

 array([   40,    28,    36,    34, 16012])

我想做 的(没有 for 循环)是根据最后一列的值对列求和,以便提供的结果是:

 array([[   6,    8,   10,   12, 4000],
       [  12,    4,    6,    8, 4002],
       [   8,   10,   12,    4, 4004],
       [  14,    6,    8,   10, 4006]])

我意识到没有循环可能会很困难,但希望最好……

如果必须使用 for 循环,那将如何工作?

我尝试 np.sum(arr[:, 4]==2000, axis=0) (我将用for循环中的变量替换 2000 ),但是它给出了 2 的结果

原文由 Infinity Cliff 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 328
2 个回答

您可以使用 np.diffnp.add.reduceat 的巧妙应用在纯 numpy 中执行此操作。 np.diff 将为您提供最右侧列发生变化的索引:

 d = np.diff(arr[:, -1])

np.where 会将您的布尔索引 d 转换为 np.add.reduceat 期望的整数索引:

 d = np.where(d)[0]

reduceat 也将期望看到零索引,并且所有内容都需要移动一个:

 indices = np.r_[0, e + 1]

使用 np.r_ 这里比 np.concatenate 更方便一点,因为它允许标量。然后总和变为:

 result = np.add.reduceat(arr, indices, axis=0)

这当然可以组合成一个单行:

 >>> result = np.add.reduceat(arr, np.r_[0, np.where(np.diff(arr[:, -1]))[0] + 1], axis=0)
>>> result
array([[   6,    8,   10,   12, 4000],
       [  12,    4,    6,    8, 4002],
       [   8,   10,   12,    4, 4004],
       [  14,    6,    8,   10, 4006]])

原文由 Mad Physicist 发布,翻译遵循 CC BY-SA 3.0 许可协议

我发布了一个简单的解决方案 pandas 和一个 itertools

 import pandas as pd
df = pd.DataFrame(arr)
x = df.groupby(4).sum().reset_index()[range(5)] #range(5) adjusts ordering
x[4] *= 2
np.array(x)

array([[   6,    8,   10,   12, 4000],
       [  12,    4,    6,    8, 4002],
       [   8,   10,   12,    4, 4004],
       [  14,    6,    8,   10, 4006]])

您还可以使用 itertools

 np.array([sum(x[1]) for x in itertools.groupby(arr, key = lambda k: k[-1])])

array([[   6,    8,   10,   12, 4000],
       [  12,    4,    6,    8, 4002],
       [   8,   10,   12,    4, 4004],
       [  14,    6,    8,   10, 4006]])

原文由 rafaelc 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题