代码之家  ›  专栏  ›  技术社区  ›  Mad Physicist

如何将最后一个索引显式指定给np.ufunc.reduceat还原

  •  0
  • Mad Physicist  · 技术社区  · 6 年前

    data = np.arange(6)
    

    我想用 np.add.reduceat 1

    np.add.reduceat(data, [0, 6, 3])[::2]
    

    我立刻得到一个错误

    IndexError: index 6 out-of-bounds in add.reduceat [0, 6)
    

    如果我这样做

    np.add.reduceat(data, [0, 5, 3])[::2]
    

    我得到了错误的答案(10应该是15):

    array([10, 12])
    

    我能想到的唯一解决办法是屏蔽需要最后一个索引的位置,从中减去1,然后再把最后一个元素加回去:

    index = np.array([0, 6, 3])
    mask = (index == data.size)
    index[mask] -= 1
    result = np.add.reduceat(data, index)
    # Mask is shifted back by one because it's the previous element that needs to be updated
    result[:-1][mask[1:]] += data[-1]
    

    result[::2] 给出想要的答案。这看起来像是一个巨大的乱七八糟的东西,我希望是一个优雅的一行(比这更快)。


    1 我是 意识到有更好的方法来做到这一点。为了说明的目的,这只是一个人为的例子。这个问题的真正问题源于试图解决这个问题 numpy: fast regularly-spaced average for large numbers of line segments / points

    1 回复  |  直到 6 年前
        1
  •  1
  •   hpaulj    6 年前

    我没用过 reduceat 很多,但看起来你只能有一个开放的范围,一个 add to the end .

    一种方法是填充数组(是的,我通常反对使用 np.append

    In [165]: np.add.reduceat(np.append(x,0),[0,6,3])
    Out[165]: array([15,  0, 12])
    

    或者使用一对完整的范围:

    In [166]: np.add.reduceat(np.append(x,0),[0,6,3,6])
    Out[166]: array([15,  0, 12,  0])
    

    我省略了通常的[::2]来澄清正在发生的事情。