Python zip方法结合NumPy舍入结果出现精度异常问题咨询
问题解析:浮点数精度限制而非
zip()的问题 这其实不是zip()方法的奇怪行为哦,本质是浮点数二进制表示的固有精度限制导致的,下面一步步拆解原因和解决办法:
问题重现
你执行的代码步骤:
import numpy as np a = np.array([1, 2, 3, 1, 1, 2, 1]) elems, counts = np.unique(a, return_counts=True) # 得到 (array([1, 2, 3]), array([4, 2, 1])) counts = np.round(counts/a.size, 3) # 打印显示 array([0.571, 0.286, 0.143]) result_dict = dict(zip(elems, counts)) # 得到 {1: 0.57099999999999995, 2: 0.28599999999999998, 3: 0.14299999999999999}
核心原因
np.round(counts/a.size, 3)虽然在打印时显示为三位小数,但NumPy使用的float64(双精度浮点数)无法精确存储像0.571、0.143这样的十进制小数——因为大部分十进制小数转换成二进制时都是无限循环的,只能存储近似值。
zip()只是单纯把两个数组的元素一一配对,并没有修改数值;当这些近似值被转换成Python原生float并显示时,就会暴露底层存储的真实近似值,而不是np.round显示的“美化后”的三位小数。
解决办法
如果需要字典里存储的是精确的三位小数数值(或显示为三位),可以试试这些方法:
- 生成字典时再做一次Python原生round处理
result_dict = {elem: round(count, 3) for elem, count in zip(elems, counts)} # 得到 {1: 0.571, 2: 0.286, 3: 0.143}
- 格式化字符串后转成float
result_dict = {elem: float(f"{count:.3f}") for elem, count in zip(elems, counts)}
- 使用NumPy的数组转列表时指定精度
如果只是需要美观的输出,也可以直接对counts数组做格式化:
print([f"{c:.3f}" for c in counts]) # 输出 ['0.571', '0.286', '0.143']
内容的提问来源于stack exchange,提问作者martina.physics
相关产品推荐
相关产品推荐

