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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19597473/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 14:08:30  来源:igfitidea点击:

Binary random array with a specific proportion of ones?

pythonarraysrandomnumpyrandom-sample

提问by Cupitor

What is the efficient(probably vectorized with Matlab terminology) way to generate random number of zeros and ones with a specific proportion? Specially with Numpy?

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

As my case is special for 1/3, my code is:

由于我的情况是特殊的1/3,我的代码是:

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

But is there any built-in function that could handle this more effeciently at least for the situation of K/Nwhere K and N are natural numbers?

但是,至少对于K/NK 和 N 是自然数的情况,是否有任何内置函数可以更有效地处理这个问题?

采纳答案by Abhijit

If I understand your problem correctly, you might get some help with numpy.random.shuffle

如果我正确理解你的问题,你可能会得到一些关于numpy.random.shuffle 的帮助

>>> def rand_bin_array(K, N):
    arr = np.zeros(N)
    arr[:K]  = 1
    np.random.shuffle(arr)
    return arr

>>> rand_bin_array(5,15)
array([ 0.,  1.,  0.,  1.,  1.,  1.,  0.,  0.,  0.,  1.,  0.,  0.,  0.,
        0.,  0.])

回答by Warren Weckesser

You can use numpy.random.binomial. E.g. suppose fracis the proportion of ones:

您可以使用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

回答by mdml

A simple way to do this would be to first generate an ndarraywith the proportion of zeros and ones you want:

一个简单的方法是首先生成一个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])

Then you can just shufflethe array, making the distribution random:

然后你可以只是shuffle数组,使分布随机:

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

Note that this approach will give you the exact proportionof zeros/ones you request, unlike say the binomial approach. If you don't need the exact proportion, then the binomial approach will work just fine.

请注意,与二项式方法不同,此方法将为您提供所需的零/一的确切比例。如果您不需要确切的比例,那么二项式方法就可以正常工作。

回答by Jaime

Yet another approach, using np.random.choice:

另一种方法,使用np.random.choice

>>> np.random.choice([0, 1], size=(10,), p=[1./3, 2./3])
array([0, 1, 1, 1, 1, 0, 0, 0, 0, 0])

回答by Galactic Ketchup

Simple one-liner: you can avoid using lists of integers and probability distributions, which are unintuitive and overkill for this problem in my opinion, by simply working with bools first and then casting to intif necessary (though leaving it as a boolarray should work in most cases).

简单的单行:您可以避免使用整数列表和概率分布,在我看来,这对于这个问题来说是不直观和矫枉过正的,只需bool先使用s 然后int在必要时强制转换(尽管将其保留为bool数组应该可以在在大多数情况下)。

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

回答by joelostblom

Another way of getting the exact number of ones and zeroes is to sample indices without replacement using np.random.choice:

获取 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

Out:

出去:

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