我的程序运行时间过长时遇到问题。我不确定它是无限运行的还是真的很慢



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

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

import numpy as np
import pandas as pd
data = pd.read_csv(r'C:UserswilloDesktopTF_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 多分钟而没有任何结果,所以我假设我做错了什么。

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

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

该行:

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

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

如果ni是数百万,这种不必要的向量乘法(数百万个零)将非常昂贵。

您可能一开始就不是要用s = np.zeros(ni)覆盖s = startcoeff的值。

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

非numpy等价物如下(改用迭代工具):

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(...函数调用通过数组并调用 lambda 函数,当前总和以r为单位,配对元素以d为单位。 对于ml计算,这对应于r = (ml[i-1],_)d = (0,raw[i]).

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

这需要 9.7 秒来处理列表中的 8,477,960 个项目。

最新更新