【问题标题】:Series Summation in PythonPython中的系列求和
【发布时间】:2018-03-29 09:11:32
【问题描述】:

我有一个 5 000 000 个元素的一维矩阵 (A),我想对这些数据进行一系列求和,以便结果(矩阵“B”)也是一个 5 000 000 个元素长的一维矩阵,其中每个元素 B[i] 是元素 A[i] 和 A[i] 之前所有元素的总和。

下面的代码是我目前所拥有的。该代码并没有完全削减它,因为执行系列中每个求和的运行时间随着求和的数量(索引值)而减少,直到进程最终在完成之前自行终止(即,在达到第 5 百万个索引之前)。

有没有更有效的方法来总结这么长的系列?是否有一个 python 函数可以做到这一点?

import numpy as np
# Create the fake data:
A = np.arange(5000000)
B = np.zeros([5000000])
for i in np.arange(5000000):
    B[i] = np.sum(A[0:i])

【问题讨论】:

    标签: python python-2.7 numpy


    【解决方案1】:

    您所描述的称为累积求和,NumPy 有一个内置函数:

    B = np.cumsum(A)
    

    如果你想自己写,你应该使用属性B[i] = B[i-1] + A[i]。也就是说,i'th 的总和等于(i-1)'th 的总和加上Ai'th 的值:

    B = np.zeros(5000000)
    for i in xrange(1, 5000000):
        B[i] = B[i-1] + A[i]
    

    这具有 O(n) 复杂性,而不是您问题中的算法的 O(n²)。另请注意,我使用的是xrange 而不是np.arange。这在循环时会更好,因为xrange 一次生成一个整数,这意味着它消耗的内存比np.arange 少。

    【讨论】:

    • 太棒了!这正是我正在寻找的那种功能!也感谢您在第二个答案中编写的更具教学性的代码!
    • 是否还有处理 NaN 值的 np.cumsum() 版本(类似于 np.nansum() )? (因为我在 A 中有一些 NaN)我尝试使用 np.nancumsum() 但我收到错误消息:“'module' object has no attribute 'nancumsum'”或者之前将我的 NaN 值设置为零更容易用 np.cumsum() 求和?
    • 我认为不是直接的。如果您只想跳过NaNs,您可以在求和之前删除它们:np.cumsum(A[~np.isnan(A)])。这里,np.isnan(A) 是一个布尔掩码,它告诉 A 中的元素 NaN 的位置。然后将其翻转为使用~ 告诉元素不是 NaN 的位置。使用它作为A 本身的索引现在只选择那些不是NaN 的元素。
    【解决方案2】:

    您可以利用B[i-1] 是它之前所有数字的总和这一事实。这意味着下一个元素 (B[i]) 就是 B[i-1]+A[i]。这将节省在迭代期间通过 A[0]A[i] 的迭代。

    这是一个可以做到这一点的函数:

    def sumMatrix(A):
        #Define the return array, B, populated with 0
        B = [0]
        #Iterate through the provided array, A
        for number in A:
            #Set the next element to the sum of the last element in B
            #  and the next number in A
            B.append(B[-1] + number)
        #Return B, removing the 0 in the first element
        return B[1:]
    
    #Call the function with the numbers from 1 to 5,000,000 and output
    #  the result
    print(sumMatrix(range(5000000)))
    

    希望这会有所帮助:)

    【讨论】:

    • 谢谢!你们今天真的用解决方案宠坏了我(和其他 python 初学者)!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 1970-01-01
    • 2019-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-24
    相关资源
    最近更新 更多