0

I would like to make a list that contains value of '1's than other random number.

let's say I want 60% of '1's appear out of 10 elements. so 6 elements of 1s and 4 elements with random. here is how I approached.

import numpy as np
import random

# to avoid generating 1s..
list_60 = np.random.randint(2,11, 10) 

array([ 6,  2,  8,  6,  6,  3,  5, 10,  6,  8])


count = 0
percentage = int(len(list_60)*(0.6) + 0.5)
for i in range(0,len(list_60)):
    if count < percentage:
        list_60[i]=0
    count += 1

list_60
array([ 1,  1,  1,  1,  1,  1,  5, 10,  6,  8])


random.shuffle(list_60)
array([ 1,  1,  1,  6,  1,  5,  1,  1,  8, 10])

Precedure STEPS:

  1. create randint from 2 to 10.
  2. loop each element and based on the percentage. and change the element to 1s.
  3. shuffle the list for more variation.

I don't think this is smart way of generating more 1s. Is there fancy/smart way to create weighted randomness?

Any help would be appreciated.

4
  • Does it need to be an exact amount of 1s in the result; or do you want to choose each value independently, with a bias? Also, why are you using Numpy for this? Commented Feb 15, 2022 at 1:29
  • Yes it has to be exact amount of 1s. 60% of 10 elements in the list. So 6 elements of 1s should be there in the list. I used numpy library to generate randoms. Commented Feb 15, 2022 at 1:34
  • thanks just edited! Commented Feb 15, 2022 at 1:41
  • Initialize the list to have exactly six 1's, then add four more random numbers. Commented Feb 15, 2022 at 2:01

1 Answer 1

1

You can get a random subset of indices, and then set those indices with 1:

import numpy as np

arr = np.random.randint(2, 11, 10)
index = np.random.choice(len(arr), int(len(arr) * 0.6), replace=False)
arr[index] = 1

print(arr)

You can also do this without numpy:

import random

arr = [random.randint(2, 11) for _ in range(10)]
index = random.sample(range(len(arr)), int(len(arr) * 0.6))
for i in index:
    arr[i] = 1

print(arr)

The above two implementations use 10 + 6 random bits. You technically only need 4 + 4 (4 for the random numbers, and 4 for their random positions (thanks to @KellyBundy for noticing this). You can achieve this in numpy with:

import numpy as np

arr = np.ones(10)
index = np.random.choice(len(arr), int(len(arr) * 0.4), replace=False)
arr[index] = np.random.randint(2, 11, len(index))

print(arr)

Or even simpler using plain python:

import random

arr = [1] * 10
for i in random.sample(range(len(arr)), int(len(arr) * 0.4)):
    arr[i] = random.randint(2, 11)

print(arr)
Sign up to request clarification or add additional context in comments.

4 Comments

How about minimizing the use of random data? Like, instead of 10+6, only 4+4 random numbers.
The shuffle one looks like 4+10 to me, though I guess the 10 might use decreasing numbers of random bits. What I meant is this, and I'm curious about the best numpy way to do that (I'm a numpy noob).
you're right, still 10+4, lemme give it another crack
edited my response to fix the error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.