调用numpy.fft.fftn执行三维FFT时出现真值歧义报错如何修复
问题背景
本人编程经验较浅,当前参与的项目需要使用numpy.fft.fftn实现互相关计算,大部分代码由Matlab代码移植而来,运行时出现报错。
问题代码段
def rot90_3D(T): T=numpy.flip(numpy.flip(numpy.flip(T,0),1),2); return(T) T_size = [T.shape[0],T.shape[1],T.shape[2]]; I_size = [I.shape[0],I.shape[1],I.shape[2]]; TI=[] for i in range(0,3,1): TI1=T_size[i]+I_size[i] TI=numpy.append(TI,TI1) one=numpy.ones((1,3)) outsize = TI - one; FT = numpy.fft.fftn(rot90_3D(T),outsize);
输入的T为shape=(51,51,51)的float32类型数组,元素取值均在0到1之间,多数为类似0.131866的小数。
报错信息
运行后抛出如下错误:
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
完整错误追踪:
Traceback (most recent call last): File "C:\Users\Grant\OneDrive\Desktop\SearchParticle Test.py", line 53, in <module> FT = numpy.fft.fftn(T2,outsize); File "<__array_function__ internals>", line 5, in fftn File "C:\Users\Grant\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py", line 813, in fftn return _raw_fftnd(a, s, axes, fft, norm) File "C:\Users\Grant\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py", line 705, in _raw_fftnd a = function(a, n=s[ii], axis=axes[ii], norm=norm) File "<__array_function__ internals>", line 5, in fft File "C:\Users\Grant\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py", line 214, in fft inv_norm = _get_forward_norm(n, norm) File "C:\Users\Grant\anaconda3\lib\site-packages\numpy\fft\_pocketfft.py", line 79, in _get_forward_norm if n < 1: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
错误原因
numpy.fft.fftn的第二个参数s要求传入一维整数序列,每个元素对应当前维度做FFT的长度。问题代码中one = numpy.ones((1,3))生成的是形状为(1,3)的二维数组,和一维的TI数组做广播减法后,得到的outsize是形状为(1,3)的二维数组。FFT内部遍历维度取长度时,拿到的是一个一维数组而非单个整数,在执行if n < 1的真值判断时,就触发了多元素数组无法直接判断布尔值的错误。
修复方案
- 修正
outsize的维度,保证其为一维整数序列,不要生成多余的二维ones数组做减法,直接通过数组运算得到正确尺寸。 - 简化冗余代码:三维翻转可以直接给
numpy.flip传入多个轴参数一次完成,不需要嵌套三次flip;尺寸计算不需要写循环逐元素追加,直接用numpy数组的形状运算即可。
修复后的可运行代码:
import numpy def rot90_3D(T): # 一次完成三个轴的翻转,和原三次嵌套flip效果完全一致 return numpy.flip(T, axis=(0, 1, 2)) # 直接将shape转为numpy数组做运算,不需要循环逐元素计算 T_size = numpy.array(T.shape) I_size = numpy.array(I.shape) # 直接计算互相关需要的FFT尺寸,结果为一维长度3的整数数组 outsize = T_size + I_size - 1 # 显式指定s参数传入outsize,避免参数位置歧义 FT = numpy.fft.fftn(rot90_3D(T), s=outsize)
内容的提问来源于stack exchange,提问作者Grant
相关产品推荐
相关产品推荐

