在Python数组中计算每5个元素的总和

12

我有一个Python数组,想要计算每五个元素的总和。在我的案例中,我有一个带有十个元素的数组c。(实际上它有更多元素。)

c = [1, 0, 0, 0, 0, 2, 0, 0, 0, 0]

所以最终我想要一个新数组 (c_new),它应该显示前5个元素和后5个元素的总和。

所以结果应该是这样的一种情况。

1+0+0+0+0 = 1
2+0+0+0+0 = 2

c_new = [1, 2]

感谢您的帮助 Markus


这是一个针对pandas系列的示例,应该适用于现有情况 - https://dev59.com/1J3ha4cB1Zd3GeqPbuyY - Divakar
5个回答

19
您可以使用 np.add.reduceat,通过传递您想要拆分和求和的索引:
import numpy as np
c = [1, 0, 0, 0, 0, 2, 0, 0, 0, 0]
np.add.reduceat(c, np.arange(0, len(c), 5))
# array([1, 2])

谢谢大家,这真是一个优雅的方法! - Markus

11

这是一种方法 -

c = [1, 0, 0, 0, 0, 2, 0, 0, 0, 0]
print [sum(c[i:i+5]) for i in range(0, len(c), 5)]

结果 -

[1, 2]

我的代码也很相似:[sum(x for x in c[i*5:5*(i+1)]) for i in range(len(c)//5)],但你的更好。 - Ma0
1
我倾向于在这种情况下使用itertools文档中的“grouper”配方,https://docs.python.org/2/library/itertools.html#recipes - [sum(group) for group in grouper(c, 5, 0)]。虽然在这里可能有些过度。 - Peter DeGlopper
1
itertools 的配方中有一些很棒的东西。 - Peter DeGlopper

5
如果您的向量长度可以被5整除,且它是连续的,则:
np.reshape(c, (-1, 5)).sum(axis=-1)

即使它是非连续的,它也能工作,但通常效率较低。

基准测试:

def aredat():
    return np.add.reduceat(c, np.arange(0, len(c), 5))

def reshp():
    np.reshape(c, (-1, 5)).sum(axis=-1)

c = np.random.random(10_000_000)

timeit(aredat, number=100)
3.8516048429883085
timeit(reshp, number=100)
3.09542763303034

因此,在可能的情况下,reshape似乎更快一些;reduceat的优点是可以优雅地处理非五的倍数向量。


1
@Divakar 为什么这么快? .sum 可以说是最主流的函数之一。它应该已经进行了大量的优化! - Paul Panzer
据我所知,它避免了一些检查,但对于“sum”来说确实很令人难过! :) - Divakar

0

有多种方法可以实现这一点。以下将介绍两种使用numpy内置方法的选项。


选项1

使用numpy.sumnumpy.ndarray.reshape函数,如下所示:

c_sum = np.sum(np.array(c).reshape(-1, 5), axis=1)

[Out]: array([1, 2])

选项2

使用numpy.vectorize、自定义lambda函数和numpy.arange,如下所示:

c_sum = np.vectorize(lambda x: sum(c[x:x+5]))(np.arange(0, len(c), 5))

[Out]: array([1, 2])

0
为什么不使用这个?
np.array([np.sum(i, axis = 0) for i in c.reshape(c.shape[0]//5,5,c.shape[1])])

为什么呢?为什么OP要使用它? - Simas Joneliunas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接