使用 SciPy stft 函数为短时傅立叶变换指定段中的样本数
Specify number of samples in a segment for Short-time Fourier Transform using SciPy stft function
我想对我的数据执行短时傅里叶变换,每个片段都有特定的样本长度。我想使用信号子模块中的 SciPy 函数 stft
。但是,当我通过以下方式创建长度为 10e5
的音频数组时:
fs = 10e3 # Sampling frequency
N = 1e5 # Number of samples
time = np.arange(N) / fs
x = 500*np.cos(time) # Some random audio wave
# x.shape gives (100000,)
并应用 SciPy stft
函数和 nperseg=1000
,我没有得到预期的 100 段。相反,输出的形状是:
f, t, Zxx = signal.stft(x, fs, nperseg=1000)
print(Zxx.shape) # -> (501, 201)
如果我对文档理解正确,501是"frequency baskets"的数量,20001是不同时间段的数量,我本来打算是N/nperseg或10e5 / 1000 = 100 .我确实看到该函数有一些参数来指定填充和重叠,但是在 N
被 nperseg
整除的情况下,它到底做了什么?
当我运行你的代码片段:
In [1]: import numpy as np
In [2]: import scipy.signal as signal
In [3]: fs = 10e3 # Sampling frequency
...: N = 1e5 # Number of samples
...: time = np.arange(N) / fs
...: x = 500*np.cos(time) # Some random audio wave
...:
In [4]: f, t, Zxx = signal.stft(x, fs, nperseg=1000)
...: print(Zxx.shape) # -> (501, 20001)
...:
(501, 201)
我看到 Zxx
的输出是 501 x 201。
501就是你说的frequency bins的个数(每段1000个temporal bins,real-only FFT后变成501个frequency bins;如果要full complex FFT,可以传入return_onesided=False
).
201 是因为 nperseg
和 noverlap
的组合。 docs 表示 noverlap
是“段之间重叠的点数。如果 None
,noverlap = nperseg // 2
。”所以 STFT 不是 制作 1e5/1e3=1e2 “段”,它通过 500 个样本(半段)重叠 1e3 长的段,所以你最终得到的比200 重叠 段。
要得到你想要的,说 noverlap=0
:
In [7]: f, t, Zxx = signal.stft(x, fs, nperseg=1000, noverlap=0)
In [8]: Zxx.shape
Out[8]: (501, 101)
我不太确定为什么 returns 101 段而不是 100 段……
signal.stft 获得了默认的 window 50% 的重叠,这大约使段数翻了一番。
在 google 中搜索 "stft overlap" 将帮助您了解有关此重叠的更多信息。
我想对我的数据执行短时傅里叶变换,每个片段都有特定的样本长度。我想使用信号子模块中的 SciPy 函数 stft
。但是,当我通过以下方式创建长度为 10e5
的音频数组时:
fs = 10e3 # Sampling frequency
N = 1e5 # Number of samples
time = np.arange(N) / fs
x = 500*np.cos(time) # Some random audio wave
# x.shape gives (100000,)
并应用 SciPy stft
函数和 nperseg=1000
,我没有得到预期的 100 段。相反,输出的形状是:
f, t, Zxx = signal.stft(x, fs, nperseg=1000)
print(Zxx.shape) # -> (501, 201)
如果我对文档理解正确,501是"frequency baskets"的数量,20001是不同时间段的数量,我本来打算是N/nperseg或10e5 / 1000 = 100 .我确实看到该函数有一些参数来指定填充和重叠,但是在 N
被 nperseg
整除的情况下,它到底做了什么?
当我运行你的代码片段:
In [1]: import numpy as np
In [2]: import scipy.signal as signal
In [3]: fs = 10e3 # Sampling frequency
...: N = 1e5 # Number of samples
...: time = np.arange(N) / fs
...: x = 500*np.cos(time) # Some random audio wave
...:
In [4]: f, t, Zxx = signal.stft(x, fs, nperseg=1000)
...: print(Zxx.shape) # -> (501, 20001)
...:
(501, 201)
我看到 Zxx
的输出是 501 x 201。
501就是你说的frequency bins的个数(每段1000个temporal bins,real-only FFT后变成501个frequency bins;如果要full complex FFT,可以传入return_onesided=False
).
201 是因为 nperseg
和 noverlap
的组合。 docs 表示 noverlap
是“段之间重叠的点数。如果 None
,noverlap = nperseg // 2
。”所以 STFT 不是 制作 1e5/1e3=1e2 “段”,它通过 500 个样本(半段)重叠 1e3 长的段,所以你最终得到的比200 重叠 段。
要得到你想要的,说 noverlap=0
:
In [7]: f, t, Zxx = signal.stft(x, fs, nperseg=1000, noverlap=0)
In [8]: Zxx.shape
Out[8]: (501, 101)
我不太确定为什么 returns 101 段而不是 100 段……
signal.stft 获得了默认的 window 50% 的重叠,这大约使段数翻了一番。 在 google 中搜索 "stft overlap" 将帮助您了解有关此重叠的更多信息。