玩了几个小时的Whack-A-Mole后,我放弃了:我想很好地打印出FFT的结果,抑制所有"几乎"数值不准确造成的实值元素。
首次尝试:
import numpy as np
n = np.arange(10)
x = np.sin(np.pi * n / 5)
X = np.fft.fft(x)
print(np.real_if_close(X))
这不起作用;我猜想,如果所有元素都是"几乎"那么虚部就会被抑制。真实的(否则数组中的数据类型将不相同)。这是对的吗?
使用循环的下一次尝试有效,但格式化很难看:
for i in range(10):
print(np.real_if_close(X[i]))
所以我尝试使用打印格式:
for i in range(10):
print("{0:5.5g}".format(X[i]))
它可以工作,但现在小的虚部回来了。尝试将两种尝试结合起来都会失败,因为臭名昭着的" non-empty format string passed to object.__format__
"错误(我使用Python 3.5):
for i in range(10):
print("{0:g}".format(np.real_if_close(X[i])))
有人可以解释这种行为吗?也许建议一个解决方案......
答案 0 :(得分:0)
数组是类型定义的(dtype),因此如果你有一个只有一个复数值的numpy数组,那么类型将是复杂的,因此所有值都存储为复数。
如果仅打印输出值,则应使用列表而不是numpy数组或仅使用循环。 X2列表提供了自制解决方案。如果你真的想使用real_if_close,那么你应该使用numpy.asscalar将类型numpy.array转换为格式为“:g”的标量值。
X = [1+1e-14j,1+1e-13j]
eps = np.finfo(float).eps
tol = 100 # tolerance (used in real_if_close)
X2 = [np.real(x) if np.imag(x)<tol*eps else x for x in X]
X3 = [np.asscalar(np.real_if_close(x)) for x in X]
for x in X3:
print("{:.5g}".format(x))