【问题标题】:Extract arbitrary subtotals from 2D numpy array从二维 numpy 数组中提取任意小计
【发布时间】:2020-10-12 02:33:05
【问题描述】:

我有 2D 计数数组,我需要从中提取任意小计序列。在本例中,它们是小计。每个小计都是基列的任意集合的总和,由 addend-indices 的元组表示:

>>> 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 循环来创建单个小计列的元组?

请注意,加数索引是任意的;并非所有指标都需要出现在小计中,指标不一定按升序出现,同一个指标可以出现在多个小计中。

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    试试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)

    【讨论】:

    • 嗯,这是一个非常有趣的方法,所以基本上创建一个新的单个数组,其中包含 all 加数列,然后在每个小计组中 reduceat() 它们。这是一个聪明的主意:)
    • @scanny 更改索引顺序是numpy 数组中的常见做法,请不要犹豫,更频繁地尝试:)
    【解决方案2】:

    由于我们不能使用np.take,这是我的解决方案(lambda 函数中还有一个 for 循环...)

    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)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-14
      • 2016-06-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多