Python 使用numpy创建十进制数的范围无效
我想用步骤0.1创建一个介于521和522之间的值范围。这是我的代码:Python 使用numpy创建十进制数的范围无效,python,numpy,rounding,Python,Numpy,Rounding,我想用步骤0.1创建一个介于521和522之间的值范围。这是我的代码: ICD9CD1 = np.arange(521, 522, 0.1) 结果是: array([521. , 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8, 521.9]) 但当我想将其转换为列表时,结果如下: np.arange(521, 522, 0.1).tolist() [521.0, 521.1, 521.2, 521.3000
ICD9CD1 = np.arange(521, 522, 0.1)
结果是:
array([521. , 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8,
521.9])
但当我想将其转换为列表时,结果如下:
np.arange(521, 522, 0.1).tolist()
[521.0,
521.1,
521.2,
521.3000000000001,
521.4000000000001,
521.5000000000001,
521.6000000000001,
521.7000000000002,
521.8000000000002,
521.9000000000002]
我的代码哪一部分是错误的?我希望此列表作为我的输出:
[521. , 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8,
521.9]试试这个:
import numpy as np
list(np.around(np.arange(521, 522, 0.1),2))
arange
docs警告:
使用非整数步长(如0.1)时,结果通常不会改变
保持一致。对于这些情况,最好使用numpy.linspace
您看到的是浮点不精确性和生成连续值的arange
方式的组合。浮点值从来都不是精确的
arange
建议使用linspace
进行分步操作。请小心选择正确的号码:
In [301]: np.linspace(521,522,11)
Out[301]:
array([521. , 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8,
521.9, 522. ])
In [302]: np.linspace(521,522,11).tolist()
Out[302]: [521.0, 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8, 521.9, 522.0]
生成整数值,并对其进行缩放:
In [303]: (np.arange(5210,5220)/10)
Out[303]:
array([521. , 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8,
521.9])
In [304]: (np.arange(5210,5220)/10).tolist()
Out[304]: [521.0, 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8, 521.9]
这也可以通过python的范围来实现:
In [305]: [i/10 for i in range(5210,5220)]
Out[305]: [521.0, 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8, 521.9]
您应该使用np.arange(52105220)/10
或np.linspace(521522,10,endpoint=False)
,但要阅读整个答案
部分代码是错误的,但不是您的思维方式
浮点运算有舍入错误。这是浮点运算的基础,也是在资源有限的计算机上进行实数计算的基本限制。即使是符号计算也不能解决问题——当一个表达式不能被符号化简化时,你最终只能构建巨大的表达式树,而不是实际计算任何东西
输出中存在舍入误差并不意味着你做错了什么。此外,arange
输出中已经存在舍入错误,只是NumPy的默认打印设置隐藏了舍入错误-在tolist
调用中没有引入舍入错误。对于任何稍不重要的浮点计算,您永远无法消除所有舍入误差
即使看起来像[521,521.1,521.2,521.3,521.4,521.5,521.6,521.7,521.8,521.9]
的结果实际上也会有舍入误差,因为实数521.1实际上不能用二进制浮点表示。大多数看起来像在那个列表中的数字不能用二进制浮点表示。(64位)浮点521.1
实际上是521.1000000000022737675443232059477777559765625
,但大多数编程语言在默认情况下不显示确切的值
代码中真正错误的部分是将arange
与浮点输入一起使用arange
与浮点输入不一致,因为基于舍入误差,它的元素可能比预期的多或少。比如说,
np.arange(1, 1.3, 0.1)
返回
array([1. , 1.1, 1.2, 1.3])
而不是
array([1. , 1.1, 1.2])
由于计算结果长度时存在浮点舍入误差
此外,由于一些奇怪的实现决策,带有浮点输入的
arange的舍入误差比它在获得正确的输出大小时应有的误差要大得多
np.linspace
旨在避免arange
的问题。它直接将输出大小作为参数,而不是从步骤中计算输出大小,并且有一个明确的参数来确定是否包含正确的端点。这避免了输出大小计算中的舍入错误,只要您不通过浮点计算输出大小来引入舍入错误np。在计算输出元素时,linspace
比arange的舍入误差更小。不能保证舍入误差尽可能小-例如,np.linspace(0,3,148)[:49]。tolist()
显示过多的舍入误差-但它比浮点arange
好得多
np.arange(52105220)/10
使用带有整数参数的arange
,然后进行除法。此选项只有一个舍入误差源,即除以10。IEEE 754规范保证此除法正确四舍五入,因为结果将四舍五入到最接近理想实数除法结果的浮点值。此选项保证舍入误差最小,在某些情况下优于linspace
。例如,np.arange(148)/49
在舍入误差方面胜过np.linspace(0,3148)
。我想你指的是arange
文档,而不是argparse
文档。@user2357112supportsMonica,是的。我在想另一个问题。