使用 numpy 创建十进制数范围不起作用
Create a range of decimal number using numpy does not work
我想创建一个介于 521 和 522 之间的值范围,步长为 0.1。这是我的代码:
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
文档警告:
When using a non-integer step, such as 0.1, the results will often not
be consistent. It is better to use numpy.linspace
for these cases.
您看到的是浮点不精确和生成连续值的 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 的 range
:
来完成
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(5210, 5220) / 10
或 np.linspace(521, 522, 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.1000000000000227373675443232059478759765625
,但大多数编程语言默认情况下不会显示确切的值。
您的代码中真正错误的部分是使用 arange
和浮点输入。 arange
与浮点输入不一致,因为根据舍入误差,它可能包含比预期更多或更少的元素。例如,
np.arange(1, 1.3, 0.1)
returns
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(5210, 5220) / 10
使用带有整数参数的 arange
然后除法。此选项只有一个舍入误差来源,即除以 10。IEEE 754 规范保证此除法 正确舍入 ,因为结果将舍入为浮点数最接近除法的理想实数结果的点值。此选项保证最小舍入误差,在某些情况下优于 linspace
。例如,np.arange(148) / 49
在舍入误差方面优于 np.linspace(0, 3, 148)
。
我想创建一个介于 521 和 522 之间的值范围,步长为 0.1。这是我的代码:
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
文档警告:
When using a non-integer step, such as 0.1, the results will often not be consistent. It is better to use
numpy.linspace
for these cases.
您看到的是浮点不精确和生成连续值的 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 的 range
:
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(5210, 5220) / 10
或 np.linspace(521, 522, 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.1000000000000227373675443232059478759765625
,但大多数编程语言默认情况下不会显示确切的值。
您的代码中真正错误的部分是使用 arange
和浮点输入。 arange
与浮点输入不一致,因为根据舍入误差,它可能包含比预期更多或更少的元素。例如,
np.arange(1, 1.3, 0.1)
returns
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(5210, 5220) / 10
使用带有整数参数的 arange
然后除法。此选项只有一个舍入误差来源,即除以 10。IEEE 754 规范保证此除法 正确舍入 ,因为结果将舍入为浮点数最接近除法的理想实数结果的点值。此选项保证最小舍入误差,在某些情况下优于 linspace
。例如,np.arange(148) / 49
在舍入误差方面优于 np.linspace(0, 3, 148)
。