【问题标题】:Numpy: How to calculate sums of array slices using indeces?Numpy:如何使用索引计算数组切片的总和?
【发布时间】:2018-10-14 13:15:14
【问题描述】:

我有一个矩阵 M:

M = [[10, 1000],
 [11, 200],
 [15, 800],
 [20, 5000],
 [28, 100],
 [32, 3000],
 [35, 3500],
 [38, 100],
 [50, 5000],
 [51, 100],
 [55, 2000],
 [58, 3000],
 [66, 4000],
 [90, 5000]]

还有一个矩阵R:

 [[10 20]
  [32 35]
  [50 66]
  [90 90]]

我想将矩阵 R 的第 0 列中的值用作切片的起始值,并将第 1 列中的值用作切片的结尾。

我想从矩阵 M 的右列计算这些切片的范围之间的总和,包括这些切片的范围。

基本做

  M[0:4][:,1].sum() # Upper index +1 as I need upper bound including
  M[5:7][:,1].sum() # Upper index +1 as I need upper bound including

等等。 0 是 10 的索引,3 是 20 的索引。5 是 32 的索引,6 是 35 的索引。

我被困在如何将矩阵 R 的开始/结束值按矩阵 M 的第 0 列转换为索引。然后计算包括上限/下限在内的索引范围之间的总和。

预期输出:

[[10, 20, 7000], # 7000 = 1000+200+800+5000
 [32, 35, 6500], # 6500 = 3000+3500
 [50, 66, 14100], # 14100 = 5000+100+2000+3000+4000
 [90, 90, 5000]] # 5000 = just 5000 as upper=lower boundary

更新,我现在可以使用 searchsorted 获取索引。现在我只需要在开始和结束的矩阵 M 的第 1 列使用 sum。

 start_indices = [0,5,8,13]
 end_indices = [3,6,12,13]

想知道是否有比应用 for 循环更有效的方法?

编辑:在这里找到答案。 Numpy sum of values in subarrays between pairs of indices

【问题讨论】:

    标签: python numpy


    【解决方案1】:

    使用searchsorted 确定正确的索引,使用add.reduceat 执行求和:

    >>> idx = M[:, 0].searchsorted(R) + (0, 1)
    >>> idx = idx.ravel()[:-1] if idx[-1, 1] == M.shape[0] else idx.ravel()
    >>> result = np.add.reduceat(M[:, 1], idx)[::2]
    >>> result
    array([ 7000,  6500, 14100,  5000])
    

    详情:

    由于您想包含上限,但 Python 将其排除在外,因此我们必须添加 1。

    reduceat 不能将 len(arg0) 作为索引处理,我们必须特殊情况

    reduceat 计算连续边界之间的所有延伸,我们必须每隔一个丢弃一个

    【讨论】:

    • @FrancWeser 我在发帖后看到你大多是自己想出来的。仍然认为这些细节可能有用。
    • 是的,非常有用,因为你的方式比我的快 2 倍。我遇到了类似的问题,您看到任何解决方案吗?谢谢。 stackoverflow.com/questions/52841655/…
    【解决方案2】:

    我认为最好显示一个您期望的输出示例。如果您想使用 M[0:4][:,1].sum() 计算的结果是 1000 + 200 + 800 + 5000 的总和。那么这段代码可能会有所帮助:

    import numpy as np
    
    M = np.matrix([[10, 1000],
     [11, 200],
     [15, 800],
     [20, 5000],
     [28, 100],
     [32, 3000],
     [35, 3500],
     [38, 100],
     [50, 5000],
     [51, 100],
     [55, 2000],
     [58, 3000],
     [66, 4000],
     [90, 5000]])
    
    
    print(M[0:4][:,1].sum())
    

    【讨论】:

      猜你喜欢
      • 2017-06-24
      • 2014-05-07
      • 2015-01-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多