使用复杂和/或真实元素打印格式良好的numpy数组(real_if_close)

时间:2018-01-31 11:57:20

标签: python arrays numpy format

玩了几个小时的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])))

有人可以解释这种行为吗?也许建议一个解决方案......

1 个答案:

答案 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))