3

我想生成 0 到 0.5 之间的均匀分布的随机数,但截断到小数点后 2 位。

没有截断,我知道这是由

import numpy as np
rs = np.random.RandomState(123456)
set = rs.uniform(size=(50,1))*0.5

任何人都可以帮助我就如何生成最多 2 dp 的随机数提出建议吗?谢谢!

4

4 回答 4

5

A float cannot be truncated (or rounded) to 2 decimal digits, because there are many values with 2 decimal digits that just cannot be represented exactly as an IEEE double.

If you really want what you say you want, you need to use a type with exact precision, like Decimal.

Of course there are downsides to doing that—the most obvious one for numpy users being that you will have to use dtype=object, with all of the compactness and performance implications.

But it's the only way to actually do what you asked for.

Most likely, what you actually want to do is either Joran Beasley's answer (leave them untruncated, and just round at print-out time) or something similar to Lauritz V. Thaulow's answer (get the closest approximation you can, then use explicit epsilon checks everywhere).

Alternatively, you can do implicitly fixed-point arithmetic, as David Heffernan suggests in a comment: Generate random integers between 0 and 50, keep them as integers within numpy, and just format them as fixed point decimals and/or convert to Decimal when necessary (e.g., for printing results). This gives you all of the advantages of Decimal without the costs… although it does open an obvious window to create new bugs by forgetting to shift 2 places somewhere.

于 2013-05-10T21:28:10.683 回答
3

小数不会被截断到小数点后 2 位……但是它们的字符串表示可能

import numpy as np
rs = np.random.RandomState(123456)
set = rs.uniform(size=(50,1))*0.5

print ["%0.2d"%val for val in set]
于 2013-05-10T21:16:24.190 回答
3

这个怎么样?

np.random.randint(0, 50, size=(50,1)).astype("float") / 100

也就是说,创建 0 到 50 之间的随机整数,然后除以 100。

编辑:

正如评论中明确指出的那样,由于内存中浮点表示的性质,这不会为您提供精确的两位小数。看起来您的数组中有确切的浮点数,0.1但绝对不是0.1. 但它非常接近,您可以通过使用“双”数据类型来让它更接近。

您可以通过将数字保留为整数来推迟这个问题,并记住在使用它们时它们要除以​​ 100。

hundreds = random.randint(0, 50, size=(50, 1))

那么至少直到最后一分钟才会发生舍入(或者可能根本不会发生,如果等式的分子是分母的倍数)。

于 2013-05-10T21:19:34.103 回答
0

I managed to find another alternative:

import numpy as np
rs = np.random.RandomState(123456)
set = rs.uniform(size=(50,2))
for i in range(50):
    for j in range(2):
        set[i,j] = round(set[i,j],2)
于 2013-05-10T21:33:29.853 回答