Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 改进等距列表上的sum()计算_Python_Numpy - Fatal编程技术网

Python 改进等距列表上的sum()计算

Python 改进等距列表上的sum()计算,python,numpy,Python,Numpy,我有一个代码,其中需要1000万个0到1之间的等距数字,我有一个逻辑函数,负责选择一个随机索引,并返回从该索引到列表末尾的数字总和 因此代码如下所示 import random import numpy as np ten_million = np.linspace(0.0, 1.0, 10000000) def deep_dive_logic(): # this pick is derived from good logic, however, let's just use ran

我有一个代码,其中需要1000万个0到1之间的等距数字,我有一个逻辑函数,负责选择一个随机索引,并返回从该索引到列表末尾的数字总和

因此代码如下所示

import random
import numpy as np

ten_million = np.linspace(0.0, 1.0, 10000000)

def deep_dive_logic():
    # this pick is derived from good logic, however, let's just use random here for demonstration
    pick = random.randint(0, 10000000)
    return sum(ten_million[pick:])

for _ in range(2500):
  r = deep_dive_logic()
  print(r)

  # more logic ahead...
这里的问题是,在这样一个大小的列表中,I loopsum(),每个结果大约需要1.3秒

有没有有效的方法来减少每次调用1.3秒的等待时间?我也尝试过创建一种缓存字典,但是deep\u dive\u logic()函数在多进程环境中运行,因此需要缓存该字典,redis或json.dump都不是一个选择,因为字典的大小装载到236MB左右,如果不缓存,则会增加进程间通信的开销

sums_dict = {0: sum(ten_million)}
even_difference = (ten_million[1] - ten_million[0])

for i in range(len(ten_million) - 1):
    sums_dict[i+1] = sums_dict[i] - (even_difference * (i+1))
我需要有关缓存1000万字典或替代公式的帮助,以便在不使用sum()或任何现成解决方案的情况下返回结果。

np.sum(一千万)
大约在0.005秒内完成,而
sum(一千万)
在我的机器上大约是1.5秒

至于不使用任何现成函数的解决方案,正如MrT对您的问题的评论中所建议的,您可以使用算术级数的属性,即级数的和等于
n(a1+an)/2
,其中
n
是元素数(10000000),a1是第一个元素(0),an是最后一个元素(1)。在您的示例中,这是
10000000(0+1)/2=5000000

因此,对于深潜逻辑函数,只需返回:

def deep_dive_logic():
    pick = random.randint(0, 10000000)
    return (len(ten_million)-pick)*(ten_million[pick]+ten_million[-1]) / 2
此外,它的运算速度也非常快,事实上,比
np.sum
快得多:在我的机器上,算术级数计算平均耗时1.223e-06秒,而
np.sum
则耗时0.00577秒。有道理,看看它是怎样的一个加法,一个乘法,一个除法…

np.sum(一千万)
大约在0.005秒内完成,而
sum(一千万)
在我的机器上大约是1.5秒

至于不使用任何现成函数的解决方案,正如MrT对您的问题的评论中所建议的,您可以使用算术级数的属性,即级数的和等于
n(a1+an)/2
,其中
n
是元素数(10000000),a1是第一个元素(0),an是最后一个元素(1)。在您的示例中,这是
10000000(0+1)/2=5000000

因此,对于深潜逻辑函数,只需返回:

def deep_dive_logic():
    pick = random.randint(0, 10000000)
    return (len(ten_million)-pick)*(ten_million[pick]+ten_million[-1]) / 2
此外,它的运算速度也非常快,事实上,比
np.sum
快得多:在我的机器上,算术级数计算平均耗时1.223e-06秒,而
np.sum
则耗时0.00577秒。有道理,看看它只是一个加法、一个乘法和一个除法…

分析一下:

def cumm_sum(start, finish, steps, k):
    step = (finish - start) / steps
    pop = (finish - k) / step
    return (pop + 1) * 0.5 * (k + finish)
电话是这样的:

pick = ten_million[random.randint(0, 10000000)]
result = cumm_sum(0.0, 1.0, 10000000, pick)
进行分析:

def cumm_sum(start, finish, steps, k):
    step = (finish - start) / steps
    pop = (finish - k) / step
    return (pop + 1) * 0.5 * (k + finish)
电话是这样的:

pick = ten_million[random.randint(0, 10000000)]
result = cumm_sum(0.0, 1.0, 10000000, pick)
  • 使用数学来降低问题的复杂性:

    算术级数的和由下式给出

    (m+n)*(m-n+1)*0.5
    
  • 使用np.vectorize可加速阵列操作:

    ten_m = 10000000
    
    def sum10m_py(n):
        return (1+n)*(ten_m-n*ten_m+1)*0.5
    
    sum_np = np.vectorize(sum_py)
    
  • 选择所需的元素,然后对其应用矢量化函数

    mask = np.random.randint(0,ten_m,2500)
    
    sums = sum_np(ten_million[mask])
    
  • 使用数学来降低问题的复杂性:

    算术级数的和由下式给出

    (m+n)*(m-n+1)*0.5
    
  • 使用np.vectorize可加速阵列操作:

    ten_m = 10000000
    
    def sum10m_py(n):
        return (1+n)*(ten_m-n*ten_m+1)*0.5
    
    sum_np = np.vectorize(sum_py)
    
  • 选择所需的元素,然后对其应用矢量化函数

    mask = np.random.randint(0,ten_m,2500)
    
    sums = sum_np(ten_million[mask])
    

  • 您是否尝试过
    numpy.sum
    ?它可能更快。是的,使用
    numpy.sum
    ,在我的机器上,时间从1.5秒左右变为0.015秒。你可以解析地解决这个问题。我不理解你的问题,如果它们是等距分布的,它们是求和的显式公式。你有第一个、最后一个和元素数。您不需要其他任何东西来计算总和。您是否尝试过
    numpy.sum
    ?它可能更快。是的,使用
    numpy.sum
    ,在我的机器上,时间从1.5秒左右变为0.015秒。你可以解析地解决这个问题。我不理解你的问题,如果它们是等距分布的,它们是求和的显式公式。你有第一个、最后一个和元素数。您不需要任何其他内容来计算总和。我不确定这是否会返回有效答案
    cumm_sum(0.0,1.0,10000000,千万[5000])=4999999.250249749
    ,但是
    sum(千万[5000:])=4999998.750249899
    step
    引入了不必要的浮点错误。打印出
    pop
    查看我的意思。我不确定这是否返回有效答案
    cumm_sum(0.0,1.0,10000000,千万[5000])=499999.250249749
    但是
    sum(千万[5000:])=4999998.750249899
    步骤引入了不必要的浮点错误。打印出
    pop
    以查看我的意思。这不应该是
    ((一千万)挑选)*(一千万[pick]+一千万[-1])/2
    ?因为n是我们要添加的元素数..这不是
    ((len(一千万)-pick)*(一千万[pick]+一千万[-1])/2
    ?因为n是我们要添加的元素数。这返回
    sum_np(千万[5000]]=2.4987505e+17
    但是
    sum(千万[5000]=4999998.750249899
    谢谢,修复了函数
    sum10m_py
    中的错误。这返回
    sum_np(千万[5000]]=2.4987505e+17
    (千万[5000:])=4999998.750249899谢谢,修复了函数
    sum10m_py