运行时警告NumPy FFT的乘法

时间:2015-06-25 21:54:01

标签: python numpy fft

我正在尝试按照this比较.wav文件的方法,但收到以下警告:

valid:call.py:23: RuntimeWarning: overflow encountered in multiply
  mult = numpy.multiply(fft1, fft2)
call.py:23: RuntimeWarning: invalid value encountered in multiply
  mult = numpy.multiply(fft1, fft2)

我检查发生了什么,发现mult设置如下:

[[ inf -0.j  nan-infj  nan+infj ...,  nan+infj  nan-infj  nan+infj]
 [ inf -0.j -inf+nanj  inf+nanj ..., -inf+nanj  inf+nanj -inf+nanj]
 [ inf -0.j  nan-infj  inf+nanj ...,  nan-infj  inf+nanj  nan+infj]
 ..., 
 [ inf -0.j -inf+nanj -inf+nanj ..., -inf+nanj -inf+nanj -inf+nanj]
 [ inf -0.j -inf+nanj -inf+nanj ..., -inf+nanj -inf+nanj -inf+nanj]
 [ inf -0.j  nan-infj  nan-infj ...,  nan+infj  nan+infj  nan+infj]]

根据dsp.stackexchange上的答案,我对数据进行了零填充。这会导致无穷大吗?如何将复数值列表相乘?

更新:我已将其更改为“手动”倍增,如下所示:

mult = [i*j for (i, j) in itertools.izip(fft1, fft2)]

我的nan-inf越来越少,但仍有一些。它现在产生以下警告:

valid:call.py:26: RuntimeWarning: overflow encountered in cdouble_scalars
  mult = [i*j for (i, j) in itertools.izip(a, b)]
call.py:26: RuntimeWarning: invalid value encountered in cdouble_scalars
  mult = [i*j for (i, j) in itertools.izip(a, b)]

但它似乎更接近了。有什么想法吗?

更新2 当然,我已经忘记了解开wav块的方式。我做了一个sys.getsizeof(frames[0])来发现每个元素的大小是36.代码在这里:

def get_fft(fft_path):
    return_list = []
    frames_list = []
    chunk_size = 36
    start = 0
    wav = wave.open(fft_path, 'r')
    frames = wav.readframes(wav.getnframes())
    wav.close()

    while start+chunk_size < len(frames):
            data = struct.unpack(">fdddd", frames[start:start+chunk_size])
            frames_list.extend(data)
            start += chunk_size
            if len(frames_list) >= 1000:
                    frames_list.extend(numpy.zeros(len(frames_list)))
                    return_list.append(numpy.fft.fft(frames_list))
                    frames_list = []

    return return_list

问题最有可能在于:data = struct.unpack(">fdddd", frames[start:start+chunk_size])。字符串">fdddd"告诉unpack“get”小端(>)一个四字节的浮点数(f)和四个八字节的双精度数(d)。我很可能误解了documentation

1 个答案:

答案 0 :(得分:0)

OP解决方案:由于@rth和@Claris猜测我正在正确地解压缩数据。在sys.getsizeof()的元素上运行frames让我相信每个元素都必须以36个字节的块进行解压缩。

如另一个答案所示(我丢失了):),我不得不用较小的块解压缩帧:

data = struct.unpack(">fdddd", frames[start:start+chunk_size])

我改为:

data = struct.unpack(">H", frames[start:start+chunk_size])

我将chunk_size从36更改为2.元素方式的乘法现在正常工作,没有NaN s或Inf s。

有关struct.unpack()的更多信息,请参阅