26

I want to generate a random array of size N which only contains 0 and 1, I want my array to have some ratio between 0 and 1. For example, 90% of the array be 1 and the remaining 10% be 0 (I want this 90% to be random along with the whole array).

right now I have:

randomLabel = np.random.randint(2, size=numbers)

But I can't control the ratio between 0 and 1.

Am1rr3zA
  • 7,115
  • 18
  • 83
  • 125

5 Answers5

58

If you want an exact 1:9 ratio:

nums = numpy.ones(1000)
nums[:100] = 0
numpy.random.shuffle(nums)

If you want independent 10% probabilities:

nums = numpy.random.choice([0, 1], size=1000, p=[.1, .9])

or

nums = (numpy.random.rand(1000) > 0.1).astype(int)
user2357112
  • 260,549
  • 28
  • 431
  • 505
10

You could use a binomial distribution:

np.random.binomial(n=1, p=0.9, size=[1000])
Peter O.
  • 32,158
  • 14
  • 82
  • 96
Juip
  • 171
  • 1
  • 6
2

Without using numpy, you could do as follows:

import random
percent = 90

nums = percent * [1] + (100 - percent) * [0]
random.shuffle(nums)
mvelay
  • 1,520
  • 1
  • 10
  • 23
1

Its difficult to get an exact count but you can get approximate answer by assuming that random.random returns a uniform distribution. This is strictly not the case, but is only approximately true. If you have a truly uniform distribution then it is possible. You can try something like the following:

In [33]: p = random.random(10000)
In [34]: p[p <= 0.1] = 0
In [35]: p[p > 0] = 1
In [36]: sum(p == 0)
Out[36]: 997
In [37]: sum(p == 1)
Out[37]: 9003

Hope this helps ...

ssm
  • 5,277
  • 1
  • 24
  • 42
0

I recently needed to do something similar as part of a compression experiment. Posting the code to generate [n] random bytes with a given ration of zeros to ones for the next person who googles...

import random

from bitstring import BitArray


def get_by_fives():
    for i in range(60, 100, 5):
        percent_0 = i
        percent_1 = 100-i
        set_count = 0
        ba = BitArray(8388608) # 1MB
        for j in range(0, len(ba)):
            die_roll = random.randint(0, 100)
            set = die_roll > percent_0
            if set:
                ba.set(True, j)
                set_count +=1
        file_name = "{}_percent_bits_set".format(percent_1, percent_0)
        print("writing {} with set_count {} to disk".format(file_name, set_count))
        with open(file_name, 'wb') as f:
            ba.tofile(f)



if __name__ == "__main__":
    get_by_fives()
snerd
  • 1,238
  • 1
  • 14
  • 28