私は毎日 32hz で入ってくる大量のデータを扱っています。データを .5hz (編集: 質問は元々 1hz と指定されていましたが、提案に基づいて変更されました) にフィルター処理し、1hz にダウンサンプリングします。ダウンサンプリングには signal.resample を、signal.butter フィルターには signal.filtfilt を使用しています。ただし、これらの両方を実行した後、FFT は信号が 0.16hz 付近で減衰することを示しています。
ダウンサンプリングよりもフィルタリングする順序は重要ですか? 手続きの関係でしょうか?メソッドを正しく理解していませんか?
関連すると思われるデータを含めました
desiredFreq = 1 * 60 *60 *26
# untouched data
quickPlots(x,32) # 32 hz
# filtered
x = ft.butterLowPass(x, .5, 32)
quickPlots(x,32) # 32 hz
# resampled
x = ft.resampleData(x, desiredFreq)
quickPlots(x,1) # should be 1 hz
def butterLowPass(data,desired,original,order = 5):
""" Creates the coefficients for a low pass butterworth
filter. That can change data from its original sample rate
to a desired sample rate
Args:
----
data (np.array): data to be filtered
desirerd (int): the cutoff point for data in hz
original (int): the initial sampling rate in hz
Returns:
-------
np.array: of the data after it has been filtered
Note:
----
I find that the filter will make the data all 0's if the order
is too high. Not sure if this is my end or scipy.signal. So work with
CAUTION
References:
----------
https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.signal.butter.html
https://docs.scipy.org/doc/scipy-0.18.1/reference/generated/scipy.signal.filtfilt.html
https://en.wikipedia.org/wiki/Butterworth_filter
https://en.wikipedia.org/wiki/Low-pass_filter
https://en.wikipedia.org/wiki/Nyquist_rate
"""
nyq = .5 * original
cutoff = desired / nyq
b, a = signal.butter(order, cutoff, btype = 'lowpass', analog = False)
return signal.filtfilt(b, a, data, padlen =10)
def resampleData(data, desired):
""" Takes in a set of data and resamples the data at the
desired frequency.
Args:
----
data (np.array): data to be operated on
desired (int): the desired sampled points
over the dataset
Returns:
-------
np.array: of the resamples data
Notes:
-----
Since signal.resample works MUCH faster when the len of
data is a power of 2, we pad the data at the end with null values
and then discard them after.
"""
nOld = len(data)
thispow2 = np.floor(np.log2(nOld))
nextpow2 = np.power(2, thispow2+1)
data = np.lib.pad(
data,
(0,int(nextpow2-nOld)),
mode='constant',
constant_values = (0,0)
)
nNew = len(data)
resample = int(np.ceil(desired*nNew/nOld))
data = signal.resample(data, resample)
data = data[:desired]
return data
def quickPlots(data,fs):
import matplotlib as mpl
import matplotlib.pyplot as plt
from scipy import signal
import time
fft,pxx=signal.welch(data,fs)
plt.plot(data)
plt.show()
plt.loglog(fft,pxx)
plt.show()
FFT の写真:
編集: .5hz でフィルターするように調整した後、同じ問題が発生します。FFT の表示方法に問題があるのではないかと考えています。グラフを表示するために使用していたクイック プロットを含めました。