Python 使用numpy创建十进制数的范围无效

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

我想用步骤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.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,是的。我在想另一个问题。