如何优化这个简单但缓慢的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(值))]