代码之家  ›  专栏  ›  技术社区  ›  scanny

从2D numpy数组中提取任意小计

  •  0
  • scanny  · 技术社区  · 4 年前

    我有二维计数数组,我需要从中提取任意小计序列。在本例中,它们是小计 加数指数 :

    >>> A
    [[11, 12, 13, 14, 15]
     [21, 22, 23, 24, 25]
     [31, 32, 33, 34, 35]]
    
    >>> subtotal_addend_idxs
    ((0, 1), (1, 2, 3), (3, 4))
    
    >>> desired_result
    [[23, 39, 29]
     [43, 69, 49]
     [63, 99, 69]]
    

    subtotal_addend_idxs = ((0, 1), (1, 2, 3), (3, 4))
    np.hstack(
        tuple(
            np.sum(A[:, subtotal_addend_idxs], axis=1, keepdims=True)
            for addend_idxs in self._column_addend_idxs
        )
    )
    

    有没有一个聪明的方法可以用一个 numpy 我不需要一个 for

    请注意,加法索引是任意的;并非所有索引都需要出现在小计中,这些索引不一定按递增顺序出现,而且同一索引可以出现在多个小计中。

    0 回复  |  直到 4 年前
        1
  •  1
  •   mathfux    4 年前

    尝试 np.add.reduceat :

    lens = [len(n) for n in subtotal_addend_idxs]
    c = np.concatenate(subtotal_addend_idxs)
    output = np.add.reduceat(A[:,c], np.cumsum([0]+lens)[:-1], axis=1)
    

    输出:

    array([[23, 39, 29],
           [43, 69, 49],
           [63, 99, 69]], dtype=int32)
    

    np.concatenate 会是 np.fromiter(itertools.chain(*subtotal_addend_idxs), dtype=int) .

        2
  •  0
  •   meTchaikovsky    4 年前

    np.take ,这是我的解决方案(在 lambda 功能…)

    test = np.array([[11, 12, 13, 14, 15],
                     [21, 22, 23, 24, 25],
                     [31, 32, 33, 34, 35]])
    inds = ((0, 1), (1, 2, 3), (3, 4))
    
    fake_take = lambda array,inds:[np.sum(array[list(ind)]) for ind in inds]
    np.apply_along_axis(lambda x:fake_take(x,inds),1,test)