Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用for循环中的find_peaks从数据文件中查找峰值高度以计算平均值_Python_Numpy - Fatal编程技术网

Python 使用for循环中的find_peaks从数据文件中查找峰值高度以计算平均值

Python 使用for循环中的find_peaks从数据文件中查找峰值高度以计算平均值,python,numpy,Python,Numpy,这个问题是关于使用scipy.signal中的find_peaks有效地从数据文件中提取平均峰高。我是Python(3.7)的初学者,所以我不确定在速度和代码质量方面是否以最佳方式编写了代码 我有一套测量文件,每个文件包含一百万个数据点(30MB)。该数据的图形是一个具有固定间隔峰值和噪声的信号。此外,信号的基线和振幅随信号的不同部分而变化。我附上了一个例子的图片。信号可能不那么干净 我的目标是计算每个文件峰值的平均高度。为了做到这一点,首先我使用find_peaks来定位所有峰值。然后,我在

这个问题是关于使用scipy.signal中的find_peaks有效地从数据文件中提取平均峰高。我是Python(3.7)的初学者,所以我不确定在速度和代码质量方面是否以最佳方式编写了代码

我有一套测量文件,每个文件包含一百万个数据点(30MB)。该数据的图形是一个具有固定间隔峰值和噪声的信号。此外,信号的基线和振幅随信号的不同部分而变化。我附上了一个例子的图片。信号可能不那么干净

我的目标是计算每个文件峰值的平均高度。为了做到这一点,首先我使用find_peaks来定位所有峰值。然后,我在每个峰值位置上循环,并在峰值周围的小间隔内检测峰值,以确保获得峰值的局部高度

然后我把所有这些高度放在numpy数组中,然后计算它们的平均值和标准偏差

这是我的代码的一个赤裸裸的版本,有点长,但我认为这也可能是因为我做错了什么

将numpy导入为np
从scipy.signal导入查找\u峰值
#为值分配空列表
平均高度=[]
标准高度=[]
平均_基线=[]
标准单位基线=[]
温度=[]
#循环几个文件,读入它们并处理数据
对于文件列表中的文件:
附加(文件)
#从30 MB的文件加载数据
t_dat,x_dat=np.loadtxt(文件,分隔符='\t',unpack=True)
#查找此文件中的所有峰值
峰值,峰值属性=查找峰值(x_dat,突出度=峰值阈值,宽度=0)
#计算窗口大小,确保其均匀
如果为圆形(len(t_dat)/len(peaks))%2==0:
每个窗口的点数=整数(长(t数据)/长(峰值))
其他:
每窗口点数=int(len(t_dat)/len(peaks)+1)
t_切片=t_数据[-1]/len(t_数据)
#为存储高度分配np数组
基线列表=np.0(长度(峰值)-2)
高度列表=np.0(长度(峰值)-2)
#循环所有发现的峰值,并在峰值周围的窗口中重新检测峰值,以便
#检测其局部高度而不触发到远处的基线
对于范围(0,len(峰值)-2)内的i:
#在峰值周围创建一个窗口
sub_t=t_dat[峰值[i+1]-每个窗口的点//2:峰值[i+1]+每个窗口的点//2]
sub_x=x_dat[peaks[i+1]-每个_窗口的点//2:peaks[i+1]+每个_窗口的点//2]
#检测峰值(2个版本,特定于我拥有的应用程序)
突出度阈值奇数=最大值(sub_x)-np.平均值(sub_x)
sub_peaks_baseline,sub_peak_baseline_properties=查找_peaks(sub_x,突出度=突出度\u阈值\u单数,距离=每个窗口的点\u-1,宽度=0)
子峰高度,子峰高度属性=查找子峰(np.append(最小(子峰x)-1,子峰x),突出度=突出度阈值单数,距离=每个窗口的点数-1,宽度=0)
#将高度添加到存储高度的np数组中
基线列表[i]=次峰值基线属性[“突出物”]
高度列表[i]=次峰值高度属性[“突出物”]
#用值填充列表,用高度获取np数组的标准差和平均值
平均高度。追加(np.平均(高度列表))
标准高度附加(np.std(高度列表))
平均值基线。追加(np.平均值(基线列表))
标准基线追加(np.std(基线列表))
我希望它运行得相当快,但是执行起来需要几十秒。这对我来说似乎很慢,所以我开始认为我可能做这个分析效率低下。我的代码中是否有某些方面没有以正确的方式完成?还是我低估了执行此计算所需的时间


提前感谢所有想看一看的人。

同时,我通过使用Python profiler发现的各种低效问题,提高了速度。我将在此处列出按速度重要性排序的优化:

  • 对I/O使用pandas
    pd.read\u csv()
    而不是
    np.loadtxt()
    切断大约90%的运行时间。如前所述,这节省了大量时间。这意味着改变这一点:

    t_-dat,x_-dat=np.loadtxt(文件,分隔符='\t',unpack=True)
    
    为此:

    data=pd.read\u csv(文件,分隔符=“\t”,名称=[“t\u dat”,“x\u dat”])
    t_dat=data.values[:,0]
    x_dat=data.values[:,1]
    
  • 删除冗余的len()调用。我注意到len()被多次调用,然后注意到这是不必要的。更改此选项:

    如果为圆形(len(t_dat)/len(peaks))%2==0:
    每个窗口的点数=整数(长(t数据)/长(峰值))
    其他:
    每窗口点数=int(len(t_dat)/len(peaks)+1)
    
    为此:

    points\u per\u window=圆形(len(t\u dat)/len(peaks))
    如果每个窗口有%2个点!=0:
    每窗口点数+=1
    
    事实证明,这也是一项重大改进

  • 最后,内置Python函数min()、max()和sum()使用了不相称的计算时间(约20%)。由于我已经在使用numpy数组,因此在这些函数中切换到numpy等价物,这一部分得到了84%的改进。这意味着例如将
    max(sub_x)
    更改为
    sub_x.max()

这些都是不相关的优化,我仍然认为对像我这样的Python初学者可能有用,它们确实帮助很大