numpy arange函数返回数组不一致现象的原因咨询
为什么numpy.arange()处理浮点数时会出现不一致的终止值?
这事儿太常见了,本质完全不是numpy的bug——罪魁祸首是浮点数的二进制精度限制,属于计算机表示小数时的天生特性。
咱们日常用的十进制小数,很多没法转换成有限长度的二进制小数,比如0.1,在二进制里是无限循环的。所以计算机存储这些小数时,只能存一个近似值。当你用arange做累加操作时,这些近似值的误差会慢慢累积,最后就干扰了arange判断“是否到达终止值”的逻辑。
具体到你的例子分析
numpy.arange的设计逻辑是生成[start, start+step, start+2*step, ...]序列,直到下一个值大于等于stop时停止(理论上是半开区间[start, stop))。但因为浮点数的近似:
- 当起始值是
0.12时,多次累加0.01后的结果,和你传入的0.16在浮点表示上可能刚好略小于等于终止值,所以被包含进了结果; - 而起始值是
0.11或0.13时,累加后的最终值和0.16的浮点近似值对比,已经略大于终止值,所以被排除在外。
你可以试着用repr()打印这些浮点数的真实存储值,就能看到明显的差异:
>>> repr(0.12) '0.12000000000000001' >>> repr(0.01) '0.010000000000000002'
怎么解决这个问题?
如果需要精确控制序列的范围和长度,推荐两个方案:
- 用
np.linspace()替代:它直接指定生成的点数,完全避开累加误差。比如你要从0.12到0.16生成5个点,直接写:
这样能精准包含首尾值,不会出现随机的长度变化。np.linspace(0.12, 0.16, num=5) - 转成整数运算:把所有数值放大成整数,用整数版的
arange计算后再缩小回去,彻底避免浮点误差:np.arange(12, 17, 1)/100 # 注意这里stop用17,因为整数arange是左闭右开
内容的提问来源于stack exchange,提问作者RoB
相关产品推荐
相关产品推荐

