生成 0.1 到 1.0 之间的随机数。Python
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16288749/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Generate random number between 0.1 and 1.0. Python
提问by user2320923
I'm trying to generate a random number between 0.1 and 1.0.
We can't use rand.randintbecause it returns integers.
We have also tried random.uniform(0.1,1.0), but it returns a value >= 0.1 and < 1.0, we can't use this, because our search includes also 1.0.
我正在尝试生成一个介于 0.1 和 1.0 之间的随机数。我们不能使用,rand.randint因为它返回整数。我们也尝试过random.uniform(0.1,1.0),但它返回一个值 >= 0.1 和 < 1.0,我们不能使用它,因为我们的搜索也包括 1.0。
Does somebody else have an idea for this problem?
其他人对这个问题有什么想法吗?
采纳答案by Elmar Peise
How "accurate" do you want your random numbers? If you're happy with, say, 10 decimal digits, you can just round random.uniform(0.1, 1.0)to 10 digits. That way you will include both 0.1and 1.0:
你想要你的随机数有多“准确”?如果您对 10 位十进制数字感到满意,则可以四舍五入random.uniform(0.1, 1.0)为 10 位数字。这样,您将同时包含0.1和1.0:
round(random.uniform(0.1, 1.0), 10)
To be precise, 0.1and 1.0will have only half of the probability compared to any other number in between and, of course, you loose all random numbers that differ only after 10 digits.
准确地说,0.1与1.0介于两者之间的任何其他数字相比,概率只有一半,当然,您会丢失所有仅在 10 位数字后不同的随机数。
回答by Simon
According to the Python 3.0 documentation:
根据 Python 3.0文档:
random.uniform(a, b) Return a random floating point number N such that a <= N <= b for a <= b and b <= N <= a for b < a.
随机的。统一(a, b) 返回一个随机浮点数 N 使得 a <= N <= b 用于 a <= b 并且 b <= N <= a 用于 b < a。
Thus, random.uniform()does, in fact, include the upper limit, at least on Python 3.0.
因此,random.uniform()实际上,至少在 Python 3.0 上确实包括上限。
EDIT: As pointed out by @Blender, the documentation for Python 3.0 seems to be inconsistent with the source code on this point.
编辑:正如@Blender 所指出的,Python 3.0 的文档在这一点上似乎与源代码不一致。
EDIT 2: As pointed out by @MarkDickinson, I had unintentionally linked to the Python 3.0 documentation instead of the latest Python 3 documentation herewhich reads as follows:
编辑 2:正如@MarkDickinson 所指出的,我无意中链接到 Python 3.0 文档而不是最新的 Python 3 文档,其内容如下:
random.uniform(a, b) Return a random floating point number N such that a <= N <= b for a <= b and b <= N <= a for b < a.
The end-point value b may or may not be included in the range depending on floating-point rounding in the equation a + (b-a) * random().
随机的。统一(a, b) 返回一个随机浮点数 N 使得 a <= N <= b 用于 a <= b 并且 b <= N <= a 用于 b < a。
取决于等式 a + (ba) * random() 中的浮点舍入,端点值 b 可能包含或不包含在范围内。
回答by jabaldonedo
You can use random.randint simply by doing this trick:
您可以通过执行以下技巧来使用 random.randint :
>>> float(random.randint(1000,10000)) / 10000
0.4362
if you want more decimals, just change the interval to:
如果您想要更多小数,只需将间隔更改为:
(1000,10000) 4 digits (10000,100000) 5 digits etc
(1000,10000) 4 位 (10000,100000) 5 位等
回答by erdekhayser
Are you unable to use random.random()? This gives a number between 0.0 and 1.0, though you could easily set up a way to get around this.
你无法使用random.random()吗?这给出了一个介于 0.0 和 1.0 之间的数字,但您可以轻松设置一种方法来解决这个问题。
import random
def randomForMe():
number = random.random()
number = round(number, 1)
if (number == 0):
number = 0.1
This code would give you a number that is between 0.1 and 1.0, inclusive (0.1 and 1.0 are both possible solutions). Hope this helps.
这段代码会给你一个介于 0.1 和 1.0 之间的数字(0.1 和 1.0 都是可能的解决方案)。希望这可以帮助。
*I assumed you only wanted numbers to the tenths place. If you want it different, where I typed round(number, 1)change 1to 2for hundredths, 3for thousandths, and so on.
*我假设你只想要十分之一的数字。如果你想要不同的,在这里我输入round(number, 1)的变化1来2为百分之一,3为千分之一,等等。
回答by dawg
You could do this:
你可以这样做:
>>> import numpy as np
>>> a=.1
>>> b=np.nextafter(1,2)
>>> print(b)
1.0000000000000002
>>> [a+(b-a)*random.random() for i in range(10)]
or, use numpy's uniform:
或者,使用numpy 的制服:
np.random.uniform(low=0.1, high=np.nextafter(1,2), size=1)
nextafterwill produce the platform specific next representable floating pointing number towards a direction. Using numpy's random.uniform is advantageous because it is unambiguous that it does not include the upper bound.
nextafter将产生平台特定的下一个可表示的浮点数朝向一个方向。使用 numpy 的 random.uniform 是有利的,因为它不包含上限是明确的。
Edit
编辑
It does appear that Mark Dickinson's comments is correct: Numpy's documentationis incorrect regarding the upper bound to random.uniform being inclusive or not.
Mark Dickinson 的评论似乎确实是正确的:Numpy 的文档关于 random.uniform 的上限是否包含在内是不正确的。
The Numpy documentation states All values generated will be less than high.
Numpy 文档说明 All values generated will be less than high.
This is easily disproved:
这很容易被反驳:
>>> low=1.0
>>> high=1.0+2**-49
>>> a=np.random.uniform(low=low, high=high, size=10000)
>>> len(np.where(a==high)[0])
640
Nor is the result uniform over this limited range:
在此有限范围内,结果也不一致:
>>> for e in sorted(set(a)):
... print('{:.16e}: {}'.format(e,len(np.where(a==e)[0])))
...
1.0000000000000000e+00: 652
1.0000000000000002e+00: 1215
1.0000000000000004e+00: 1249
1.0000000000000007e+00: 1288
1.0000000000000009e+00: 1245
1.0000000000000011e+00: 1241
1.0000000000000013e+00: 1228
1.0000000000000016e+00: 1242
1.0000000000000018e+00: 640
However, combining J.F. Sebastian and Mark Dickinson's comments, I think this works:
但是,结合 JF Sebastian 和 Mark Dickinson 的评论,我认为这有效:
import numpy as np
import random
def rand_range(low=0,high=1,size=1):
a=np.nextafter(low,float('-inf'))
b=np.nextafter(high,float('inf'))
def r():
def rn():
return a+(b-a)*random.random()
_rtr=rn()
while _rtr > high:
_rtr=rn()
if _rtr<low:
_rtr=low
return _rtr
return [r() for i in range(size)]
If run with the minimal spread of values in Mark's comment such that there are very few discrete floating point values:
如果在 Mark 的注释中以最小的值分布运行,则离散浮点值很少:
l,h=1,1+2**-48
s=10000
rands=rand_range(l,h,s)
se=sorted(set(rands))
if len(se)<25:
for i,e in enumerate(se,1):
c=rands.count(e)
note=''
if e==l: note='low value end point'
if e==h: note='high value end point'
print ('{:>2} {:.16e} {:,}, {:.4%} {}'.format(i, e, c, c/s,note))
It produces the desired uniform distribution inclusive of end points:
它产生所需的均匀分布,包括端点:
1 1.0000000000000000e+00 589, 5.8900% low value end point
2 1.0000000000000002e+00 544, 5.4400%
3 1.0000000000000004e+00 612, 6.1200%
4 1.0000000000000007e+00 569, 5.6900%
5 1.0000000000000009e+00 593, 5.9300%
6 1.0000000000000011e+00 580, 5.8000%
7 1.0000000000000013e+00 565, 5.6500%
8 1.0000000000000016e+00 584, 5.8400%
9 1.0000000000000018e+00 603, 6.0300%
10 1.0000000000000020e+00 589, 5.8900%
11 1.0000000000000022e+00 597, 5.9700%
12 1.0000000000000024e+00 591, 5.9100%
13 1.0000000000000027e+00 572, 5.7200%
14 1.0000000000000029e+00 619, 6.1900%
15 1.0000000000000031e+00 593, 5.9300%
16 1.0000000000000033e+00 592, 5.9200%
17 1.0000000000000036e+00 608, 6.0800% high value end point
On the values requested by the OP, it also produces a uniform distribution:
在 OP 请求的值上,它还产生均匀分布:
import matplotlib.pyplot as plt
l,h=.1,1
s=10000
bin_count=20
rands=rand_range(l,h,s)
count, bins, ignored = plt.hist(np.array(rands),bin_count)
plt.plot(bins, np.ones_like(bins)*s/bin_count, linewidth=2, color='r')
plt.show()
Output
输出


回答by John Y
With the information you've given (including comments thus far), I still fail to see how the university is going to test your program such that it will make a difference if 1.0 appears or not. (I mean, if you're required to generate randomfloats, how can they require that anyparticular value appears?)
根据您提供的信息(包括迄今为止的评论),我仍然看不到大学将如何测试您的程序,以便在 1.0 出现与否时会产生影响。(我的意思是,如果您需要生成随机浮点数,他们如何要求出现任何特定值?)
OK, so putting the craziness of your requirements aside:
好的,所以把你的要求放在一边:
The fact that the lower bound for your random floats is higher than 0 gives you a disturbingly elegant way to use random.random, which guarantees return values in the interval [0.0, 1.0): Simply keep calling random.random, throwing away any values less than 0.1, except 0.0. If you actually get 0.0, return 1.0 instead.
随机浮点数的下限高于 0 的事实为您提供了一种令人不安的优雅使用方式random.random,它保证在区间 [0.0, 1.0) 中返回值:只需继续调用random.random,丢弃任何小于 0.1 的值,0.0 除外. 如果您实际得到 0.0,则返回 1.0。
So something like
所以像
from random import random
def myRandom():
while True:
r = random()
if r >= 0.1:
return r
if r == 0.0:
return 1.0
回答by Alfe
The standard way would be random.random() * 0.9 + 0.1(random.uniform()internally does just this). This will return numbers between 0.1 and 1.0 without the upper border.
标准方法是random.random() * 0.9 + 0.1(random.uniform()内部就是这样做的)。这将返回 0.1 和 1.0 之间没有上边框的数字。
But wait! 0.1 (aka 1/??) has no clear binary representation (as ? in decimal)! So You won't get a true 0.1 anyway, simply because the computer cannot represent it internally. Sorry ;-)
可是等等!0.1(又名 1/??)没有明确的二进制表示(如 ? 十进制)!所以无论如何你都不会得到真正的 0.1,仅仅是因为计算机无法在内部表示它。对不起 ;-)
回答by jfs
Random.uniform()is just:
def uniform(self, a, b):
"Get a random number in the range [a, b) or [a, b] depending on rounding."
return a + (b-a) * self.random()
where self.random()returns a random number in the range [0.0, 1.0).
whereself.random()返回范围内的随机数[0.0, 1.0)。
Python (as well as many other languages) uses floating
pointto represent real
numbers. How 0.1is represented is described in detail in the
docs:
Python(以及许多其他语言)使用浮点数来表示实数。文档中详细描述了如何0.1表示:
from __future__ import division
BPF = 53 # assume IEEE 754 double-precision binary floating-point format
N = BPF + 3
assert 0.1 == 7205759403792794 / 2 ** N
It allows to find a random number in [0.1, 1](inclusive) using
randint()without losing precision:
它允许在不丢失精度的情况下[0.1, 1]使用(包括)
找到一个随机数randint():
n, m = 7205759403792794, 2 ** N
f = randint(n, m) / m
randint(n, m)returns a random integer in [n, m](inclusive)
therefore the above method can potentially return allfloating points
numbers in [0.1, 1].
randint(n, m)返回一个随机整数 in [n, m](inclusive) 因此上述方法可以潜在地返回 中的所有浮点数[0.1, 1]。
An alternative is to find the smallest xsuch that x > 1and use:
另一种方法是找到最小的x这样x > 1并使用:
f = uniform(.1, x)
while f > 1:
f = uniform(.1, x)
xshould be the smallest value to avoid losing precision and to
reduce number of calls to uniform()e.g.:
x应该是最小值以避免丢失精度并减少调用次数,uniform()例如:
import sys
# from itertools import count
# decimal.Decimal(1).next_plus() analog
# x = next(x for i in count(1) for x in [(2**BPF + i) / 2**BPF] if x > 1)
x = 1 + sys.float_info.epsilon
Both solutions preserve uniformness of the random distribution (no skew).
两种解决方案都保持随机分布的均匀性(无偏斜)。
回答by user2844536
Try random.randint(1, 10)/100.0
尝试 random.randint(1, 10)/100.0
回答by Mitar
In numpy, you can do the following:
在 numpy 中,您可以执行以下操作:
import numpy
numpy.random.uniform(0.1, numpy.nextafter(1, 2))

