我有一个代码,我需要在0和1之间的10Million均匀间隔数字,我有一个逻辑函数,负责选择一个随机索引,返回该索引的数字总和,直到列表的末尾即可。
因此代码如下所示,
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循环 sum()在这样的大小列表上需要大约。每个结果1.3秒。
有没有有效的方法来减少每次调用的1.3s等待?我也尝试创建一种缓存字典,但是deep_dive_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))
我需要帮助缓存10万字典或替代公式,以便在不使用sum()或任何现成解决方案的情况下返回结果。
答案 0 :(得分:3)
np.sum(ten_million)
在约0.005秒内完成,而sum(ten_million)
在我的机器上约为1.5秒
对于没有使用任何现成功能的解决方案,正如MrT对你的问题的评论中所建议的那样,你可以使用算术进展的属性,它表示进展的总和等于{{1其中n(a1+an) / 2
是元素的数量(10000000),a1是你的第一个元素(0),a是你的最后一个元素(1)。在您的示例中,这是n
所以,对于你的deep_dive_logic函数,只需返回:
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
快得多:平均而言,算术级数计算需要1.223e-06秒,而np.sum
在我的机器上需要0.00577秒。有道理,看看它只是一个加法,一个乘法和一个除法......
答案 1 :(得分:1)
分析地做:
abstract type ABS{A,B} end
struct Myk <: ABS{Int64,Float64} end
struct MyStruct{A,B,K<:ABS{A,B}}
a::A
b::B
MyStruct{A,B,K}(a::A,b::B) where {A,B,K<:ABS{A,B}}= new(a,b)
end
# this is the outer constructor:
MyStruct(a::A, b::B, ::K) where {A,B,K<:ABS{A,B}} = MyStruct{A,B,K}(a,b)
# now this works:
MyStruct(1,2.1,Myk())
并且电话会像:
def cumm_sum(start, finish, steps, k):
step = (finish - start) / steps
pop = (finish - k) / step
return (pop + 1) * 0.5 * (k + finish)
答案 2 :(得分:0)
使用数学来减少问题的复杂性:
算术级数的总和由
给出(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])