如何优化这个简单但缓慢的Python';对于';环
基本上,我有一个函数,对于每一行,一次对上面的一个额外值求和,直到总和达到给定的阈值。一旦达到给定的阈值,它将获取生成的切片索引并使用它返回另一列切片的平均值如何优化这个简单但缓慢的Python';对于';环,python,numpy,loops,iteration,Python,Numpy,Loops,Iteration,基本上,我有一个函数,对于每一行,一次对上面的一个额外值求和,直到总和达到给定的阈值。一旦达到给定的阈值,它将获取生成的切片索引并使用它返回另一列切片的平均值 import numpy as np #Random data: values = np.random.uniform(0,10,300000) values2 = np.random.uniform(0,10,300000) output = [0]*len(values) #Function that operates one o
import numpy as np
#Random data:
values = np.random.uniform(0,10,300000)
values2 = np.random.uniform(0,10,300000)
output = [0]*len(values)
#Function that operates one one single row and returns the mean
def function(threshold,row):
slice_sum=0
i=1
while slice_sum < threshold:
slice_sum = values[row-i:row].sum()
i=i+1
mean = values2[row-i:row].mean()
return mean
#Loop to iterate the function row by row:
for i in range(15,len(values)): #let's just skip the first 15 values, otherwise the loop might get stuck. This issue is not prioritary though.
output[i] = function(40,i)
将numpy导入为np
#随机数据:
数值=np.随机均匀(0,10300000)
值2=np.随机均匀(0,10300000)
输出=[0]*len(值)
#操作一行并返回平均值的函数
def功能(阈值,行):
切片总和=0
i=1
当切片和<阈值时:
slice_sum=值[row-i:row].sum()
i=i+1
平均值=值2[第i行:第2行]。平均值()
回归均值
#循环以逐行迭代函数:
对于范围内的i(15,len(values)):#让我们跳过前15个值,否则循环可能会卡住。但这个问题并不是首要问题。
输出[i]=函数(40,i)
这是循环的简化版本。它可能看起来不慢,但从所有意图和实际目的来看,它都非常慢。所以我想知道是否有一种更快的方法可以在没有for循环的情况下实现这一点
谢谢您无需每次通过循环重新计算总和。您从
值[row-1:row]
(单个值)开始,如果该值足够小,则添加一个附加值。与其一次又一次地对相同的值重新求和,不如用下一个值来增加上一个和
def function(threshold, row):
slice_sum = 0
for i in range(1, len(values)+1):
slice_sum += values[row-i]
if slice_sum >= threshold:
break
return values2[row-i-1:row].mean()
这将加法运算的数量从O(n^2)减少到O(n)。您无需每次通过循环重新计算总和。您从
值[row-1:row]
(单个值)开始,如果该值足够小,则添加一个附加值。与其一次又一次地对相同的值重新求和,不如用下一个值来增加上一个和
def function(threshold, row):
slice_sum = 0
for i in range(1, len(values)+1):
slice_sum += values[row-i]
if slice_sum >= threshold:
break
return values2[row-i-1:row].mean()
这会将加法操作的数量从O(n^2)减少到O(n)。使用基于
值的累积和排序的searchsorted直接导航到下一个组。这将为您提供O(n log n)性能,其中n是值中的组数:
import numpy as np
def meanBlocks(values,values2,threshold):
sums = np.cumsum(values)
i = j = k = 0
output = np.zeros(values.size)
while j < values.size:
s = sums[j]-values[j]+threshold # s is next cumsum to reach
i,j = j,np.searchsorted(sums,s) # position of next increment by threshold
output[k] = np.mean(values2[i:j]) # track mean of values2 for range
k += 1
return output[:k]
使用按值的累积和排序的searchsorted直接导航到下一个组。这将为您提供O(n log n)性能,其中n是值中的组数:
import numpy as np
def meanBlocks(values,values2,threshold):
sums = np.cumsum(values)
i = j = k = 0
output = np.zeros(values.size)
while j < values.size:
s = sums[j]-values[j]+threshold # s is next cumsum to reach
i,j = j,np.searchsorted(sums,s) # position of next increment by threshold
output[k] = np.mean(values2[i:j]) # track mean of values2 for range
k += 1
return output[:k]
为了简化问题,您不需要将output
预先分配到任何特定的长度。只需使用output=[函数(40,i)表示范围内的i(15,len(值))]
。为了简化问题,您不需要将output
预先分配到任何特定长度。只需使用output=[函数(40,i)表示范围内的i(15,len(值))]
。