在Python中将信号下采样到特定数量的样本

信息处理 过滤器 离散信号 Python 下采样 scipy
2022-02-14 22:23:44

Python Scipy 库提供了几个函数来对信号进行下采样,但它们都有局限性:

  • 采样函数基于傅里叶方法,这意味着它假设周期信号。
  • resample_poly函数假定“超出信号边界的值为零”。
  • 抽取函数只能通过某些整数因子对信号进行下采样,而不是特定数量的样本
  • upfirdn函数需要 FIR 滤波器系数作为输入,我不确定如何获得。

我有一个不是周期性的信号,信号边界之外的值不是零,我想将信号从 611 个样本下采样到 100 个样本。

有没有一种简单的方法可以在 Python 中做到这一点?

谢谢。

编辑:我需要将信号下采样到固定数量的样本的原因是我有不同长度的信号,我想使用这些信号来训练一维 CNN 进行分类/回归任务,这需要固定大小的输入;我不喜欢使用 RNN/LSTM,尽管这些模型可以接受各种大小的输入。

3个回答

我正在使用 1D CNN 做类似于您的应用程序的事情。我认为 scipy.resample_poly 是最通用的函数,因为它允许上采样、下采样或两者的组合。

此外,您对“超出信号边界的值为零”的评论可以通过使用 padtype 中的选项“line”来解决,如函数文档中所示,以消除信号头部/尾部的虚假效应.

一般来说,如果重采样因子的整数对您来说仍然是一个问题(但它不应该因为您可以使用信号的长度),您可以使用移动平均线的组合,然后在网格上进行插值。

我会考虑你为什么真的想这样做 - 我个人想不出为什么我想降低采样到一个特定的样本数但我不知道你的项目

浮动另一个想法,您可以下采样直到接近该抽取水平然后截断?它不会完全是 100 个样本,但从长远来看,允许信号结束位置的误差容限可能会更容易

为了在寻找包时提供一些帮助 - 您正在寻找可以使用插值而不是整数因子重新采样信号的东西。

你可以自己写一个,有点工作。您将需要选择一个插值函数来配合它 - 我建议您尝试一些与不同的截断 sinc 函数一起使用,然后看看什么是有效的

首先,所有这些例程都作用于输入数组。您的评论“超出信号边界的值不是零”意味着您要处理一个连续信号,或者至少一个比单个调用和数组长的信号。如果您想使用这些例程,您需要对信号进行一些缓冲区管理。其次,为了将 611 转换为 100,使用这些例程,您需要上采样 100 和下采样 611。

由于您正在寻找“一种简单的方法”,因此我认为您需要研究 Python DSP 库。我不使用任何,但我知道这个,例如:http ://ajaxsoundstudio.com/software/pyo

但我会详细说明整数因子问题。通过整数因子转换速率很容易理解和实现——插入零向上,丢弃样本向下。DSP 书籍通常将此作为唯一选择。但是您源中的每个样本都是一种冲动。使用线性相位 FIR 抗混叠滤波器对其进行滤波会产生一个加窗的 sinc 函数。您可以在任何地方使用所有必要点的窗口化 sinc 函数。无需对采样周期的整数倍或除法执行此操作。