为什么 numpy 数组上的 set 函数会返回略有不同的值?

Why is set function on a numpy array returning slightly different values?

我必须检查矩阵是否具有多重性>1 的特征值。 使用numpy的eig函数得到一个数组,将其转化为set,应该去掉重复的特征值,比较list和set的长度,可以推断是否有重复的特征值或者not.The代码如下-

from numpy.linalg import eig
A=[[3,1,1],[2,4,2],[-1,-1,1]]
if len(eig(A)[0])!=len(set(eig(A)[0])):
    print "Multiple eigenvalues found!"
else:
    print "All distinct"

我得到的结果是 "All distinct",并检查我做了-print set(eig(A)[0])并得到了

>>>set([2.0000000000000009, 1.9999999999999998, 3.9999999999999982]) 特征值是 2,2,4 并且集合操作必须使它成为 {2,4}。但是它将一个 2 转换为 2.0000000000000009,另一个转换为 1.9999999999999998,并使它们看起来不同。

我知道,可以有其他更长的方法使用 loop/counter 来检查特征值的不同性,但为什么会这样?

正如@JohanC 所建议的,您可以使用 sympy 库,特别是这里可能的实现:

from sympy import Matrix
import numpy as np
A=[[3,1,1], [2,4,2], [-1,-1,1]]
M = Matrix(A)

# Create array with eigenvalues multiplicities
mults = np.array([m for m in M.eigenvals().values()])

if np.any(mults>1):
    print("Multiple eigenvalues found!")
else:
    print("All distinct")

我刚刚发现这也可以在不使用 numpy 的情况下完成,方法是将 float/complex 值转换为字符串并比较字符串(虽然效率不高)-

from numpy.linalg import eig
A=[[3,1,1],[2,4,2],[-1,-1,1]]
if len(set([str(elem) for elem in eig(A)[0]]))!=len([str(elem) for elem in eig(A)[0]]):
    print "Multiple eigenvalues found!"
else:
    print "All distinct"