我想对我的数据执行短时傅立叶变换,每个段的特定样本长度。我想使用信号子模块中的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是“频率篮子”的数量,20001是不同时间段的数量,我原本打算将其作为N / npereg或10e5 / 1000 = 100.我确实看到了该函数有一些参数来指定填充和重叠,但在N
被nperseg
整除的情况下,它究竟做了什么?
答案 0 :(得分:2)
当我运行您的代码段时:
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
的输出是201乘以501。
return_onesided=False
)
201是因为nperseg
和noverlap
的组合。 docs表示noverlap
是“段之间重叠的点数。如果None
,noverlap = nperseg // 2
。“因此STFT 不使1e5 / 1e3 = 1e2”段“,它将1e3长段重叠500个样本(半段) ),所以最终会有超过200个重叠的段。
要获得您想要的内容,请说noverlap=0
:
In [7]: f, t, Zxx = signal.stft(x, fs, nperseg=1000, noverlap=0)
In [8]: Zxx.shape
Out[8]: (501, 101)
我不确定为什么它会返回101段而不是100 ...
答案 1 :(得分:0)
signal.stft的默认窗口重叠率为50%,大致是段数的两倍。 在谷歌搜索“stft overlap”将帮助您了解有关此重叠的更多信息。