简体   繁体   English

基于布尔数组获取numpy数组的总和

[英]Take sum of numpy array based on a boolean array

I have two numpy arrays prods and index 我有两个numpy数组prodsindex

prods = np.asarray([ 0.5 ,  0.25,  1.98,  2.4 ,  2.1 ,  0.6 ])
index = np.asarray([False,  True,  True, False, False,  True], dtype=bool)

I need to calculate the sum of the values in prods array using the index array. 我需要使用index数组计算prods数组中值的总和。 The output I want to is 我想要的输出是

res = [0.75, 1.98, 5.1]

The first True in index array is preceded by a False , so I take the first two elements from prods (.5,.25) and sum them up(0.75). index数组中的第一个True前面是False ,因此我从prods (.5,.25)中获取前两个元素,并将它们加起来(0.75)。 The second True in index has no preceding False (since its preceded by a True , the False at position zero doesn't count), so I simply output 1.98 in this case. 第二个True in索引没有前面的False (因为它前面有True ,所以零位置的False不计数),因此在这种情况下,我只输出1.98。 The third True is preceded by two False , so I take those values from prods array (2.4,2.1,0.6) and sum them up. 第三True由两个前面False ,所以取这些值从prods阵列(2.4,2.1,0.6)和总结它们。 Any ideas on how to do this? 有关如何执行此操作的任何想法?

I basically need something like np.cumsum but I need to return the cumulative sum every time a True occurs in index and reset the cumulative sum value to zero. 我基本上需要类似np.cumsum东西,但是每次索引中出现True时,我都需要返回累积和,并将累积和值重置为零。

You could use np.split and using np.where of your index array as positions to split: 您可以使用np.split并将index数组的np.where用作拆分位置:

>>> [arr.sum() for arr in np.split(prods, np.where(index)[0]+1)[:-1]]
[0.75, 1.98, 5.0999999999999996]

The last one isn't exactly 5.1 because of floating point precision. 由于浮点精度,最后一个并非完全是5.1 If you don't want to use Fraction s or Decimal s there's nothing you can do about that. 如果您不想使用FractionDecimal那么您将无能为力。


You could also use np.add.reduceat here: 您还可以在此处使用np.add.reduceat

>>> np.add.reduceat(prods, np.append([0], (np.where(index)[0]+1)[:-1]))
array([ 0.75,  1.98,  5.1 ])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM