NumPy FFT 乘法的运行时警告
Runtime Warnings on multiplication of 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 上的回答指示,我正在用零填充我的数据。这会导致无穷大吗?我如何乘复数列表?
更新: 我已将其更改为 "manually" 像这样相乘:
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 块的 kluge 方式。我做了一个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"
告诉解压到 "get" 小尾数法 (>
) 一个四字节浮点数 (f
) 和四个八字节双精度数 (d
)。我很可能误解了 documentation.
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()。
我正在尝试按照 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 上的回答指示,我正在用零填充我的数据。这会导致无穷大吗?我如何乘复数列表?
更新: 我已将其更改为 "manually" 像这样相乘:
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 块的 kluge 方式。我做了一个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"
告诉解压到 "get" 小尾数法 (>
) 一个四字节浮点数 (f
) 和四个八字节双精度数 (d
)。我很可能误解了 documentation.
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()。