scipy.signal.resample表现得很奇怪

时间:2013-11-17 23:10:49

标签: python numpy scipy

我目前正在进行一些信号处理(使用scipy),但我遇到了一个奇怪的问题,无法弄清楚出了什么问题。也就是说,我正在从.wav文件中读取一些音频数据,但在进一步处理之前必须重新采样。该信号有超过500,000个样本。

现在,scipy.signal.resample在其中一个频道上花费的时间超过10分钟。好吧,我想,这可能是正常的,因为有很多样本。然而,然后我决定尝试另外两个“信号”(即一个随机生成的数字数组和一个零数组)和1,000,000个样本并重新采样这些信号。奇怪的是,在这种情况下重新采样只需要几毫秒,所以尺寸显然不是问题。

我的最后一个实验是从原始信号中提取零(大约有50,000个零值样本)并重新采样。我完全惊讶地发现只重新采样50,000个零需要大约一分钟。以前,我重新采样了一个零的数组,在几毫秒内有1,000,000个样本,现在我需要等待大约一分钟才能获得50,000个样本的数组。有些事情必须是错的,但我无法弄清楚是什么。

我真的没有看到任何这种行为的原因;特别是零(1,000,000和几毫秒对50,000和一分钟)让我大吃一惊。

这是一个示例代码,以便您知道我在说什么:

import scipy.io.wavfile as wavfile
import numpy
import scipy.signal as signal

sample_rate, signal_data = wavfile.read('file.wav')

test_channel = numpy.array(signal_data[:,0], dtype=float)
channel_zeros = numpy.array(signal_data[numpy.where(signal_data[:,0]==0)[0],0], dtype=float)
test_signal = numpy.random.rand((1000000))
test_signal_2 = numpy.zeros((1000000))

number_of_samples = 500

#both of these are executed in less than a second
resampled_random = signal.resample(test_signal, number_of_samples)
resampled_zeros = signal.resample(test_signal_2, number_of_samples)

#this takes minutes
resamples_original_signal = signal.resample(test_channel, number_of_samples)

#this takes about a minute
resampled_original_zeros = signal.resample(channel_zeros, number_of_samples)

你知道这可能有什么问题吗?提前谢谢。

1 个答案:

答案 0 :(得分:2)

当数据的长度为2的幂(例如2,4,8,16,32)时,FFT(基于FFTPACK)的numpy实现最快,而当它是素数时则最慢。为了加快信号的处理速度,您可以将数据填充到2的长度。

在Python中,您可以使用以下代码查找给定数字的下一个最大2的幂:

y = np.floor(np.log2(n))
nextpow2 = np.power(2, y+1)

您可以将此项与numpy.pad一起用于将数据数据填充到此大小:

sample_rate, signal_data = wavfile.read('file.wav')
n = signal_data.shape[0]

y = np.floor(np.log2(n))
nextpow2  = np.power(2, y+1)

signal_data  = np.pad(signal_data , ((0, nextpow2-n), (0,0)), mode='constant')

关于see this question中的scipy / numpy和FFT的更多背景信息。