我的程序运行时间太长了。我不确定它是无限运行还是真的很慢

时间:2019-06-19 15:45:25

标签: python

我正在编写代码以分析(8477960,1)列向量。我不确定代码中的while循环是否无限运行,或者我编写事情的方式是否真的很慢。

这是我的代码中直到第一个while循环的一部分,我无法运行到完成。

import numpy as np
import pandas as pd

data = pd.read_csv(r'C:\Users\willo\Desktop\TF_60nm_2_2.txt')


def recursive_low_pass(rawsignal, startcoeff, endcoeff, filtercoeff):
    #  The current signal length

    ni = len(rawsignal)  # signal size
    rougheventlocations = np.zeros(shape=(100000, 3))

    # The algorithm parameters
    # filter coefficient
    a = filtercoeff
    raw = np.array(rawsignal).astype(np.float)

    # thresholds
    s = startcoeff
    e = endcoeff  # for event start and end thresholds

    # The recursive algorithm
    # loop init

    ml = np.zeros(ni)
    vl = np.zeros(ni)
    s = np.zeros(ni)

    ml[0] = np.mean(raw) # local mean init
    vl[0] = np.var(raw) # local variance init
    i = 0  # sample counter
    numberofevents = 0  # number of detected events

    # main loop
    while i < (ni - 1):
        i = i + 1
        # local mean low pass filtering
        ml[i] = a * ml[i - 1] + (1 - a) * raw[i]
        # local variance low pass filtering
        vl[i] = a * vl[i - 1] + (1 - a) * np.power([raw[i] - ml[i]],2)
        # local threshold to detect event start
        sl = ml[i] - s * np.sqrt(vl[i])

我没有收到任何错误消息,但是我让程序运行了10分钟以上而没有任何结果,所以我认为我做错了事。

1 个答案:

答案 0 :(得分:0)

您应该尝试向量化此过程,而不是访问/处理索引(否则为什么使用numpy)。

另一件事是,您似乎正在做不必要的工作(除非我们没有看到整个功能)。

行:

sl = ml[i] - s * np.sqrt(vl[i])

为循环内(或其他任何地方)未使用的变量sl赋值。此赋值执行一个完整的向量乘以s,而s均为零。如果确实需要sl变量,则应使用最后遇到的ml [i]和vl [i]值在循环外进行计算,可以将它们存储在临时变量中,而不是在每个循环中进行计算。

如果ni以百万为单位,那么这种不必要的矢量乘法(数以百万计的零)将非常昂贵。

您可能并不打算首先用s = startcoeff覆盖s = np.zeros(ni)的值。

为了矢量化这些计算,您将需要使用np.acumulate和一些自定义函数。

等效的非numpy如下所示(改为使用itertools):

from itertools import accumulate

ml     = [np.mean(raw)]+[0]*(ni-1)
mlSums = accumulate(zip(ml,raw),lambda r,d:(a*r[0] + (1-a)*d[1],0))
ml     = [v for v,_ in mlSums]

vl     = [np.var(raw)]+[0]*(ni-1)
vlSums = accumulate(zip(vl,raw,ml),lambda r,d:(a*r[0] + (1-a)*(d[1]-d[2])**2,0,0))
vl     = [v for v,_,_ in vlSums]

在每种情况下,ml / vl向量都以索引为零的基值初始化,其余的则以零填充。

accumulate(zip(...函数调用遍历数组,并使用r中的当前总和和d中的成对元素来调用lambda函数。对于ml计算,它对应于r = (ml[i-1],_)d = (0,raw[i])

因为累积输出的日期类型与输入的日期类型相同(它们是压缩的元组),所以实际结果只是mlSums / vlSums列表中元组的第一个值。

处理列表中的8,477,960件商品需要9.7秒。