减少后最大值的 Numpy 索引 - numpy.argmax.reduceat

Numpy index of the maximum with reduction - numpy.argmax.reduceat

我有一个平面阵列b:

a = numpy.array([0, 1, 1, 2, 3, 1, 2])

还有一个索引数组 c,标记每个索引的开始 "chunk":

b = numpy.array([0, 4])

我知道我可以使用归约法在每个 "chunk" 中找到最大值:

m = numpy.maximum.reduceat(a,b)
>>> array([2, 3], dtype=int32)

但是...有没有办法通过矢量化操作(没有列表,循环)在块</edit>(如numpy.argmax)中找到最大值<edit>的索引)?

借用 的想法。

涉及的步骤:

  • 将组中的所有元素偏移 limit-offset。对它们进行全局排序,从而限制每个组停留在它们的位置,但对每个组内的元素进行排序。

  • 在排序后的数组中,我们将查找最后一个元素,即组最大值。它们的索引将是向下偏移组长度后的 argmax。

因此,矢量化实现将是 -

def numpy_argmax_reduceat(a, b):
    n = a.max()+1  # limit-offset
    grp_count = np.append(b[1:] - b[:-1], a.size - b[-1])
    shift = n*np.repeat(np.arange(grp_count.size), grp_count)
    sortidx = (a+shift).argsort()
    grp_shifted_argmax = np.append(b[1:],a.size)-1
    return sortidx[grp_shifted_argmax] - b

作为一个小的调整,可能会更快,我们可以选择用 cumsum 创建 shift ,因此有一个早期方法的变体,就像这样 -

def numpy_argmax_reduceat_v2(a, b):
    n = a.max()+1  # limit-offset
    id_arr = np.zeros(a.size,dtype=int)
    id_arr[b[1:]] = 1
    shift = n*id_arr.cumsum()
    sortidx = (a+shift).argsort()
    grp_shifted_argmax = np.append(b[1:],a.size)-1
    return sortidx[grp_shifted_argmax] - b