python求極值點(波峰波谷)


python求極值點主要用到scipy庫。

1. 首先可先選擇一個函數或者擬合一個函數,這里選擇擬合數據:np.polyfit

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from scipy import signal   #濾波等

xxx = np.arange(0, 1000)
yyy = np.sin(xxx*np.pi/180)

z1 = np.polyfit(xxx, yyy, 7) # 用7次多項式擬合
p1 = np.poly1d(z1) #多項式系數
print(p1) # 在屏幕上打印擬合多項式
yvals=p1(xxx) 

plt.plot(xxx, yyy, '*',label='original values')
plt.plot(xxx, yvals, 'r',label='polyfit values')
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.legend(loc=4)
plt.title('polyfitting')
plt.show()

得到的圖形是:

 

2. 求波峰值,也就是極大值,得到:signal.find_peaks,官方文檔:https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.find_peaks.html#scipy-signal-find-peaks。

scipy.signal.find_peaks(x, height=None, threshold=None, distance=None, prominence=None, width=None, wlen=None, rel_height=0.5, plateau_size=None)

Parameters:
x : sequence. A signal with peaks.
height : number or ndarray or sequence, optional. Required height of peaks. Either a number, None, an array matching x or a 2-element sequence of the former. The first element is always interpreted as the minimal and the second, if supplied, as the maximal required height.
threshold : number or ndarray or sequence, optional. Required threshold of peaks, the vertical distance to its neighbouring samples. Either a number, None, an array matching x or a 2-element sequence of the former. The first element is always interpreted as the minimal and the second, if supplied, as the maximal required threshold.
distance : number, optional. Required minimal horizontal distance (>= 1) in samples between neighbouring peaks. Smaller peaks are removed first until the condition is fulfilled for all remaining peaks.
prominence : number or ndarray or sequence, optional. Required prominence of peaks. Either a number, None, an array matching x or a 2-element sequence of the former. The first element is always interpreted as the minimal and the second, if supplied, as the maximal required prominence.
width : number or ndarray or sequence, optional. Required width of peaks in samples. Either a number, None, an array matching x or a 2-element sequence of the former. The first element is always interpreted as the minimal and the second, if supplied, as the maximal required width.
wlen : int, optional. Used for calculation of the peaks prominences, thus it is only used if one of the arguments prominence or width is given. See argument wlen in peak_prominences for a full description of its effects.
rel_height : float, optional. Used for calculation of the peaks width, thus it is only used if width is given. See argument rel_height in peak_widths for a full description of its effects.
plateau_size : number or ndarray or sequence, optional. Required size of the flat top of peaks in samples. Either a number, None, an array matching x or a 2-element sequence of the former. The first element is always interpreted as the minimal and the second, if supplied as the maximal required plateau size.
New in version 1.2.0.
# 極值
num_peak_3 = signal.find_peaks(yvals, distance=10) #distance表極大值點的距離至少大於等於10個水平單位
print(num_peak_3[0])
print('the number of peaks is ' + str(len(num_peak_3[0])))
plt.plot(xxx, yyy, '*',label='original values')
plt.plot(xxx, yvals, 'r',label='polyfit values')
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.legend(loc=4)
plt.title('polyfitting')
for ii in range(len(num_peak_3[0])):
    plt.plot(num_peak_3[0][ii], yvals[num_peak_3[0][ii]],'*',markersize=10)
plt.show()

 

3. 在可導的情形下,可以求導來求極值點,同時得到極大值和極小值點:np.polyder

yyyd = np.polyder(p1,1) # 1表示一階導
print(yyyd)

此時:yyyd.r 即可就得導數為0的點,可以與上述的極大值點對應比較

 

4. 直接函數分別求極大值和極小值:signal.argrelextrema 函數

print(yvals[signal.argrelextrema(yvals, np.greater)]) #極大值的y軸, yvals為要求極值的序列
print(signal.argrelextrema(yvals, np.greater))  #極大值的x軸
peak_ind = signal.argrelextrema(yvals,np.greater)[0] #極大值點,改為np.less即可得到極小值點
plt.plot(xxx, yyy, '*',label='original values')
plt.plot(xxx, yvals, 'r',label='polyfit values')
plt.xlabel('x axis')
plt.ylabel('y axis')
plt.legend(loc=4)
plt.title('polyfitting')
plt.plot(signal.argrelextrema(yvals,np.greater)[0],yvals[signal.argrelextrema(yvals, np.greater)],'o', markersize=10)  #極大值點
plt.plot(signal.argrelextrema(yvals,np.less)[0],yvals[signal.argrelextrema(yvals, np.less)],'+', markersize=10)  #極小值點
plt.show()

## ----- end ------

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM