为什么NumPy数组与列表判断共有元素时出现精度差异?
问题根本原因
这是浮点数二进制存储精度误差导致的,你在控制台看到的打印结果是四舍五入后的可视化值,并非数值在内存中的实际存储值。
具体逻辑
- 0.01无法用二进制浮点数精确表示,
np.arange生成浮点序列时是持续累加步长0.01的,累加过程中会累积微小的误差:比如数组a中显示为0.7的元素,实际存储值可能是0.6999999999999995,而数组b中显示为0.7的元素,实际存储值可能是0.7000000000000001,二者实际数值并不相等,set做相等判断时自然不会识别为同一个元素。 - 你复制打印结果重新赋值后判断返回True,是因为你复制的是四舍五入到两位小数的十进制文本,把这些文本转成浮点数时会生成同一个近似值,自然能匹配到交集。
- 把numpy数组转成Python列表也不会解决问题,转换过程只会把numpy的float类型转成Python的float类型,底层存储的精度误差会完整保留,不会消失。
修复方案
方案1:转整数判断(推荐,性能最优)
将两个数组都放大100倍后四舍五入转整数,消除浮点误差后再判断交集:
a_int = np.around(a * 100).astype(int) b_int = np.around(b * 100).astype(int) print(bool(set(a_int) & set(b_int)))
方案2:用带容差的相等判断
使用numpy内置的np.isclose函数,允许微小误差范围内判定为相等:
# 只要存在任意一对元素在误差范围内相等,就判定为有共有元素 has_common = np.any(np.isclose(a[:, np.newaxis], b[np.newaxis, :]))
方案3:从源头避免浮点误差
生成数组的时候先以1为步长生成整数序列,再除以100得到目标浮点序列,避免累加0.01产生的误差:
# 生成数组a的示例 start = int(np.around(d.iloc[0]['start'], 2) * 100) stop = int(np.around(d.iloc[0]['stop'], 2) * 100) a = np.arange(start, stop, 1) / 100
内容的提问来源于stack exchange,提问作者connor449
相关产品推荐
相关产品推荐

