【问题标题】:Both fast and very slow scipy.signal.resample with the same input size具有相同输入大小的快速和非常慢的 scipy.signal.resample
【发布时间】:2019-02-19 13:10:53
【问题描述】:

根据scipy.signal.resample的文档,速度应该根据输入的长度而有所不同:

如前所述,重采样使用 FFT 变换,如果输入样本的数量很大且是素数,这可能会非常慢,请参阅 scipy.fftpack.fft。

但是我有非常不同的时序(因子 x14)使用相同的输入,并且所需的输出大小只有很小的变化:

import numpy as np, time
from scipy.signal import resample

x = np.random.rand(262144, 2)
y = np.random.rand(262144, 2)

t0 = time.time()
resample(x, 233543, axis=0)
print time.time() - t0          # 2.9 seconds here

t0 = time.time()
resample(y, 220435, axis=0)
print time.time() - t0          # 40.9 seconds here!

问题:我可以对输入进行零填充,使其具有 2 的幂(以加快 FFT 计算,像往常一样),但由于我的重采样因子是固定的,我不能同时拥有 2 的幂输入大小和所需输出大小的 2 的幂

如何加速scipy.signal.resample

如果不可能,并且如果scipy.signal.resample 的性能会因很大的因素而变化如此大,那么它对于实际使用来说真的不方便。那么它对哪个应用程序有用呢?

注意:我的目标是音频重采样(重调等)

编辑:最好的解决方案终于是to use this

【问题讨论】:

  • 使用在空间域内插值的重采样函数。

标签: python numpy scipy fft resampling


【解决方案1】:

文档字符串,有点误导,陈述了故事的一部分。重采样过程包括 FFT(输入大小)、零填充和逆 FFT(输出大小)。因此,不方便的输出大小会减慢它的速度,就像不方便的输入大小一样。

Cris Luengo 建议在空间域中使用直接插值,这里应该更快。比如ndimage.zoom使用它(默认三次样条插值):

from scipy.ndimage import zoom
t0 = time.time()
zoom(y, (220435./262144., 1))   # maybe with prefilter=False ? up to you
print(time.time() - t0)         # about 200 times faster than resample

与重新采样的输出不同(毕竟是不同的方法),但对于平滑数据(与此处使用的随机输入不同),它们应该接近。

【讨论】:

  • 那么如果scipy.signal.resample 的性能可以变化如此之大,它对哪个应用程序有用?我在原帖中添加了这个问题。
  • 上采样 2 的幂 - 整数因子的数组...或者,当您不能将 SciPy 作为依赖项时重新采样。
【解决方案2】:

重采样过程包括 FFT(输入大小)、零填充和逆 FFT(输出大小)。因此,不方便的输出大小会减慢它的速度,就像不方便的输入大小一样。

只是补充一点,这仅适用于上采样。对于下采样过程是:FFT -> 乘法 -> iFFT -> 下采样。所以在下采样中,FFT/iFFT 与输出大小无关,只与输入大小有关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-31
    • 2014-08-28
    • 2016-09-16
    • 2012-07-15
    • 2013-12-19
    • 2022-01-09
    • 1970-01-01
    相关资源
    最近更新 更多