對於信號處理,Scipy 的 scipy.signal
提供了許多函式實作,信號處理是另一門專業,不在我涉獵範圍,不過倒是一些基本的函式可以聊一下。
例如,若原本有個已取樣的訊號,想要基於它重新取樣,可以使用 scipy.signal
的 resample
,例如,將已經取樣的原訊號,以 0.1 的比例重新取樣:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
freq = 10 # 頻率
stop = .25 # 取樣範圍為 0 ~ stop
sample_rate = 800 # 取樣率,單位 x 取樣幾次
resample_rate = 0.1 # 重新取樣比例
x = np.linspace(0, stop, int(stop * sample_rate), endpoint = False)
y = np.sin(freq * 2 * np.pi * x)
# 重新取樣
x1 = np.linspace(0, stop, int(stop * sample_rate * resample_rate), endpoint = False)
y1 = signal.resample(y, int(x.size * resample_rate))
plt.plot(x, y)
plt.plot(x1, y1)
plt.show()
畫出來的結果會如下,藍色是原訊號,橘色是重新取樣後的結果:
相對地,如果你有個訊號,取樣率比較低,想要模擬為更連續的曲線,可以透過 scipy.signal
的 qspline1d
、qspline1d_eval
,或者是 cspline1d
、cspline1d_eval
來達到目的,它們實現了 B-spline 的二次(quadratic)、三次曲線(cubic)功能,簡單來說,給定的點會作為控制點,作為內插計算的依據。
對於曲線的模擬,透過二次的 qspline1d
、qspline1d_eval
,或者是三次的 cspline1d
、cspline1d_eval
,通常就足夠了,如果需要自行控制 B-spline 的更多細節,可以透過 bspline
函式,當然,你就必須對 B-spline 有更多認識,想入門這部份的話,可先從〈畫說曲線〉開始。
底下示範了二次、三次的曲線模擬:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
freq = 10 # 頻率
stop = .25 # 取樣範圍為 0 ~ stop
sample_rate = 25 # 取樣率,單位 x 取樣幾次
x = np.linspace(0, stop, int(stop * sample_rate), endpoint = False)
y = np.sin(freq * 2 * np.pi * x)
# 新模擬點的 x 座標
newx = np.linspace(0, stop, int(stop * sample_rate * 5), endpoint = False)
# 舊的資料間距
dx = 1 / sample_rate
newy1 = signal.qspline1d_eval( # 計算 y 值
signal.qspline1d(y), newx, dx = dx) # 計算係數
newy2 = signal.cspline1d_eval(
signal.cspline1d(y), newx, dx = dx)
plt.plot(x, y)
plt.plot(newx, newy1)
plt.plot(newx, newy2)
plt.show()
執行結果如下,藍色是原訊號,橘色是二次,綠色是三次:
其實,對於資料的內插,scipy.interpolate
提供了更方便的相關函式,相對來說,使用上簡單許多,這樣就不另做說明了,需要範例的話,可參考官方文件的〈Interpolation (scipy.interpolate)〉。
在濾波的部份,scipy.signal
也提供了中值濾波等實作,來看看一個常見的簡單函式 detrend
:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
t = np.linspace(0, 5, 100)
x = t + np.random.normal(size=100)
x_detrended = signal.detrend(x)
plt.plot(t, x)
plt.plot(t, x_detrended)
plt.show()
簡單來說,去除訊號中具有線性變化趨勢的部份,執行後會有如下,藍色是原訊號,呈現逐漸上升的結果,橘色是去除上升趨勢後的結果: