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
Binary random array with a specific proportion of ones?
提问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/N
where K and N are natural numbers?
但是,至少对于K/N
K 和 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 frac
is 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 ndarray
with 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 shuffle
the 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 bool
s first and then casting to int
if necessary (though leaving it as a bool
array 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])