使用 numpy 创建一系列十进制数不起作用 [英] Create a range of decimal number using numpy does not work

查看:58
本文介绍了使用 numpy 创建一系列十进制数不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想以 0.1 步长创建 521 到 522 之间的值范围.这是我的代码:

I want to create a range of values between 521 and 522 with step 0.1. This is my code:

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])

但是当我想将其转换为列表时,结果如下:

but when I want to covert it to a list, this is the result:

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]

What part of my code is wrong? I want this list as my output: [521. , 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8, 521.9]

推荐答案

你应该使用 np.arange(5210, 5220)/10np.linspace(521, 522,10,endpoint=False),但阅读整个答案.

You should either use np.arange(5210, 5220) / 10 or np.linspace(521, 522, 10, endpoint=False), but read the whole answer.

你的部分代码错误,但不是你想的那样.

Part of your code is wrong, but not the way you're thinking.

浮点运算有舍入误差.这是浮点的基础,也是尝试在资源有限的计算机上执行实数计算的基本限制.即使是符号计算也无法解决问题——当一个表达式不能被符号化地简化时,你最终只会构建巨大的表达式树,而不是实际计算任何东西.

Floating-point operations have rounding error. This is fundamental to floating point, and a fundamental limitation of trying to perform real-number computations on computers with finite resources. Even symbolic computation won't fix things - when an expression can't be symbolically simplified, you end up just building giant expression trees instead of actually computing anything.

输出中仅仅存在舍入错误并不意味着您做错了什么.此外,舍入错误已经存在于 arange 输出中,只是被 NumPy 的默认打印设置隐藏了 - 它没有在 tolist 调用中引入.对于任何稍微不平凡的浮点计算,您永远无法消除所有舍入误差.

The mere presence of rounding error in your output doesn't mean you've done something wrong. Also, the rounding error was already present in the arange output, just hidden by NumPy's default print settings - it wasn't introduced in the tolist call. For any even slightly nontrivial floating point calculation, you'll never eliminate all rounding error.

即使是看起来像 [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,但大多数编程语言默认不显示确切值.

Even a result that looks like [521. , 521.1, 521.2, 521.3, 521.4, 521.5, 521.6, 521.7, 521.8, 521.9] would actually have rounding error, because the real number 521.1 is not actually representable in binary floating point. Most numbers that look like they're in that list aren't representable in binary floating point. The (64-bit) float 521.1 is actually 521.1000000000000227373675443232059478759765625, but most programming languages don't display the exact value by default.

您的代码中真正错误的部分是将 arange 与浮点输入一起使用.arange 与浮点输入不一致,因为基于舍入误差,它可能具有比预期更多或更少的元素.例如,

The part of your code that really is wrong is the use of arange with floating-point inputs. arange is inconsistent with floating-point inputs, because based on rounding error, it may have more or less elements than expected. For example,

np.arange(1, 1.3, 0.1)

返回

array([1. , 1.1, 1.2, 1.3])

而不是

array([1. , 1.1, 1.2])

因为在计算结果长度时存在浮点舍入误差.

because of floating-point rounding error in the computation of the length of the result.

此外,由于一些奇怪的实现决策,带有浮点输入的 arange 即使获得正确的输出大小,其舍入误差也比应有的要多得多.

Also, due to some weird implementation decisions, arange with floating-point inputs has a lot more rounding error than it should even when it gets the right output size.

np.linspace 旨在避免 arange 的问题.它直接将输出大小作为参数,而不是从步骤中计算它,并且有一个明确的参数来确定是否包含正确的端点.这可以避免输出大小计算中的舍入误差,只要您不通过以浮点计算输出大小来引入它.np.linspace 在输出元素的计算中也比 arange 具有更少的舍入误差.不能保证有最小的舍入误差 - 例如, np.linspace(0, 3, 148)[::49].tolist() 显示过多的舍入误差 - 但它确实比浮点arange好很多.

np.linspace is designed to avoid the problems with arange. It takes the output size as an argument directly, instead of computing it from the step, and has an explicit parameter for whether or not to include the right endpoint. This avoids rounding error in the output size computation, as long as you don't introduce it yourself by computing the output size in floating point. np.linspace also has less rounding error than arange in the computation of the output elements. It is not guaranteed to have the least rounding error possible - for example, np.linspace(0, 3, 148)[::49].tolist() shows excess rounding error - but it does a lot better than floating-point arange.

np.arange(5210, 5220)/10 使用带有整数参数的 arange 并在之后进行除法.此选项只有一个舍入误差源,即除以 10.IEEE 754 规范保证此除法正确舍入,因为结果将舍入到最接近的浮点值除法的理想实数结果.这个选项保证了最小的舍入误差,在某些情况下优于 linspace.例如,np.arange(148)/49 在舍入误差方面优于 np.linspace(0, 3, 148).

np.arange(5210, 5220) / 10 uses arange with integer arguments and divides afterward. This option has only one source of rounding error, the division by 10. This division is guaranteed by the IEEE 754 spec to be correctly rounded, in that the results will be rounded to the floating-point values closest to the ideal real-number results of the division. This option guarantees the least rounding error, beating linspace in some cases. For example, np.arange(148) / 49 beats np.linspace(0, 3, 148) in rounding error.

这篇关于使用 numpy 创建一系列十进制数不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆