Python 具有特定比例的二进制随机数组?

Python 具有特定比例的二进制随机数组?,python,arrays,random,numpy,random-sample,Python,Arrays,Random,Numpy,Random Sample,生成随机数的0和具有特定比例的1的有效方法是什么(可能用Matlab术语矢量化)?特别是和Numpy 由于我的案例是针对1/3的,因此我的代码是: import numpy as np a=np.mod(np.multiply(np.random.randomintegers(0,2,size)),3) 但是有没有任何内置函数可以更有效地处理这一问题,至少在K/N的情况下,其中K和N是自然数?您可以使用numpy.random.binomial。例如,假设frac是一个的比例: In [50

生成随机数的0和具有特定比例的1的有效方法是什么(可能用Matlab术语矢量化)?特别是和Numpy

由于我的案例是针对
1/3
的,因此我的代码是:

import numpy as np 
a=np.mod(np.multiply(np.random.randomintegers(0,2,size)),3)

但是有没有任何内置函数可以更有效地处理这一问题,至少在
K/N
的情况下,其中K和N是自然数?

您可以使用
numpy.random.binomial
。例如,假设
frac
是一个的比例:

In [50]: frac = 0.15

In [51]: sample = np.random.binomial(1, frac, size=10000)

In [52]: sample.sum()
Out[52]: 1567

一种简单的方法是首先生成一个带有所需的0和1的比例的
ndarray

>>> import numpy as np
>>> N = 100
>>> K = 30 # K zeros, N-K ones
>>> arr = np.array([0] * K + [1] * (N-K))
>>> arr
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
       0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
       1, 1, 1, 1, 1, 1, 1, 1])
然后您可以对数组进行洗牌,使分布随机:

>>> np.random.shuffle(arr)
>>> arr
array([1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0,
       1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 1, 1,
       1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1,
       0, 0, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1,
       1, 1, 1, 0, 1, 1, 1, 1])

请注意,与二项式方法不同,这种方法将为您提供所请求的0/1的确切比例。如果你不需要精确的比例,那么二项式方法就可以了。

如果我正确理解你的问题,你可能会得到一些帮助


另一种方法是使用:


简单一行:你可以避免使用整数和概率分布的列表,在我看来,这些列表对于这个问题来说是不直观的,也是多余的,只要先使用
bool
s,然后在必要时转换为
int
(尽管在大多数情况下,将其保留为
bool
数组就可以了)

>>将numpy作为np导入
>>>np.随机。随机(9)<1/3。
数组([False,True,True,True,False,False,False,False])
>>>(np.随机。随机(9)<1/3。)A型(int)
数组([0,0,0,0,0,0,1,0,0,0,1])

获取1和0的确切数量的另一种方法是使用
np.random.choice对索引进行采样,而不进行替换

arr_len = 30
num_ones = 8

arr = np.zeros(arr_len, dtype=int)
idx = np.random.choice(range(arr_len), num_ones, replace=False)
arr[idx] = 1
输出:


您是否需要比例正好是给定的值,或者这只是样本的预期比例?另外,当
size
不能被3整除时,1/3的情况会发生什么?例外?圆形/地板/特鲁克?加权随机轮(因此10有2/3的机会为3,1/3的机会为4)?@WarrenWeckesser,这是我的情况下的预期比例。我希望你没有删除你的答案,这样我就接受了。@Naji:我恢复了我的答案。如果你需要精确的比例,这个方法就行不通了。@Naji:你想要什么都行?我希望它能产生一万亿美元,而它给我的只是一个数组。我想我还没有完全相信我真蠢!对,我忘了二进制分布。事实上,有人在你之前发布了二进制文件,但他删除了他的答案(不知道为什么!!)这很聪明,注意这种方法不会给出你所请求的0和1的确切比例。下面@mdml给出的答案是will.true,既然它被接受了,我想Cupitor可能在他的program@JFFIGK,dbliss:在对问题的评论中对此进行了讨论。这些评论仍然存在,请看一看。这并不能保证像mdml的答案那样正确的评论比例。@John,这在问题的评论中已经讨论过了。看一看,我现在明白了!当然,这个问题需要编辑,因为它要求具体的比例。这并不能保证mdml答案中正确的比例。OP说他们希望1/3是1的预期比例,而不是确切的比例。
>>> np.random.choice([0, 1], size=(10,), p=[1./3, 2./3])
array([0, 1, 1, 1, 1, 0, 0, 0, 0, 0])
>>> import numpy as np
>>> np.random.random(9) < 1/3.
array([False,  True,  True,  True,  True, False, False, False, False])   
>>> (np.random.random(9) < 1/3.).astype(int)
array([0, 0, 0, 0, 0, 1, 0, 0, 1])    
arr_len = 30
num_ones = 8

arr = np.zeros(arr_len, dtype=int)
idx = np.random.choice(range(arr_len), num_ones, replace=False)
arr[idx] = 1
arr

array([0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1,
       0, 0, 0, 0, 0, 1, 0, 0])