【问题标题】:scipy.signal.spectrogram output not as expectedscipy.signal.spectrogram 输出不符合预期
【发布时间】:2017-02-11 13:26:07
【问题描述】:

我正在使用scipy.signal.spectrogram() 分析包含电流值的数据集。我对该函数的输入如下:

f, t, Sxx = signal.spectrogram(y, fs)

(用于在子图 3 中绘制(从顶部开始)我使用 plt.pcolormesh(t, f, Sxx)

其中y 是一个包含 10002 个值的列表,其中包含第一个图中绿色图形的 y 值(从顶部开始)。 fs = 1/T 其中T = x[1]-x[0] 其中x 是属于y 值(当前)的x 值(时间)列表。

我的问题是

t[-1]-t[0] != x[-1]-x[0]

含义:我想将图 3 与图 1 中的绿色图进行比较,当这两者不在同一时间跨度范围内时,频谱图变得无用。从图中可以看出total_length_x > total_length_t

为什么会这样?我该怎么做才能使光谱范围与我的原始数据在相同的时间跨度内?

【问题讨论】:

  • 请阅读docs.scipy.org/doc/scipy/reference/generated/… 了解此函数返回的内容。要生成频谱图,必须使用一组点(窗口)并计算这些值的 FFT。默认情况下,您使用的是 256 点非重叠窗口。这意味着,您的 1002 数据集将提供 40 个数据集。我假设你有 40 分 t。因此,对于每个 Sxx 列(以及每个 t),这对应于 256 个原始输入时间值。
  • 我已经阅读了文档,但我仍然不明白输出。以下是一些数字:len(t) = 44。t[-1]-t[0] = 1.92639999。 x[-1]-x[0] = 2.0001997。所以你看,我“丢失”了 0.0738 微秒的数据。
  • 我在上面关于重叠的问题上犯了一个错误。在文档中,如果未提供,则假定重叠为256/8 = 32。这意味着,您的积分将是1 + floor((10002 - 256) / (256 - 32)) = 44t 点是窗口的中间点,即 t[0] = x[128]n > 0t[n] = x[128 + (n - 1) * (256 - 32)] 。我希望这能解释它。

标签: python scipy signal-processing fft spectrogram


【解决方案1】:

我写了一些代码来解释我上面关于数据大小的cmets:

#!/usr/bin/env python

import numpy as np
import scipy.signal
from scipy.signal import spectrogram

WINDOW_LEN = 256
OVERLAP_LEN = WINDOW_LEN / 8
DATA_LEN = 10002
DURATION = 2.0001997
fs =  (DATA_LEN - 1) / DURATION
eps = 1/(fs * 1000.0)

y = np.random.rand(DATA_LEN)
x = np.arange(0, DURATION + 1/fs, 1/fs)

f, t, Sxx = spectrogram(y, fs=fs, nperseg=WINDOW_LEN)

T = np.zeros( int(1 +  np.floor((len(y) - WINDOW_LEN) / (WINDOW_LEN - OVERLAP_LEN))) )

T[0] = x[WINDOW_LEN / 2]
T[1:] = [x[WINDOW_LEN / 2 + (n + 1) * (WINDOW_LEN - OVERLAP_LEN)] for n in np.arange(0,len(T) - 1)]


if all(t - T < eps):
    print (t - T)
    print "All are fine"
    print x[-1] - x[0]
    print t[-1] - t[0]
    print T[-1] - T[0]
else:
    print t
    print T
    print "Wrong estimates"

【讨论】:

  • 非常感谢,这很好地解释了输出!我的问题现在改为:如何正确绘制这些值?因为当我在绘制plt.pcolormesh(t,f,Sxx) 时,它似乎是错误的。现在我的情节从time = t[0] 开始,而不是从time = 0 开始。那么,如何正确将此图缩放为与原始数据集 1:1 的时间比例? (ofc。如果t[0]=0,我可以用t = t + x[0] 更正偏移量。)但这不会解决我的问题,因为它们的总时间不同。
  • t,f,Sxx = self.spect_Ihv() #basically 调用 signal.spectrogram() 并返回值 new_t = [] #更改 bin for i in range(0, 45): jada = 0.045454545454545456 #2microsec/44bins = binsize new_t.append(jada * i) new_t = new_t + self.Ihv.x[0] #adjusting to original datastring ax3.pcolormesh(new_t, f, Sxx) 如果我这样做,它会缩放完美,但我不确定我所做的是否“合法”?对不起,可怕的格式......
  • 我无法正确阅读您的代码。但我能说的是,从频谱图返回的Sxx 的每一列都代表以t 为中心居中 的时间样本。问题是第一个样本(可能是最后一个)必须以不同的方式处理。通过重叠,每个t 样本代表256 - 256 / 8 时间样本x。我希望这会有所帮助。
  • Here is the same raw code used in the original post (removed two subplots)And here is the version I want, modified as showed in the code。我的code 是OO。如果有任何不清楚的地方,请告诉我。最后两行中的 ny_t 应替换为 new_t(从挪威翻译的变量名)。 self.Ihv.x[0] 是原始数据集中的第一个 x 值。我现在的问题是,这个“拉伸”版本是我应该呈现数据的方式,还是我不允许这样做?
  • 我认为我看到的唯一问题是,尽管在开始和结束时存在异常,但您将频谱引脚视为在输入数据之外等距分布。说实话,我希望可以忽略这些非常微小的细节。另一个建议,检查如何使用适当的渐变将颜色图更改为更具描述性,以显示值的变化,它看起来很平坦。
猜你喜欢
  • 2022-01-16
  • 1970-01-01
  • 1970-01-01
  • 2014-09-22
  • 1970-01-01
  • 1970-01-01
  • 2018-09-17
  • 2021-10-04
  • 2012-08-24
相关资源
最近更新 更多