-1

I have a 1D (numpy) array with boolean values. for example:

x = [True, True, False, False, False, True, False, True, True, True, False, True, True, False]

The array contains 8 True values. I would like to keep, for example, exactly 3 (must be less than 8 in this case) as True values randomly from the 8 that exist. In other words I would like to randomly set 5 of those 8 True values as False.

A possible result can be:

x = [True, True, False, False, False, False, False, False, False, False, False, False, True, False]

How to implement it?

Divakar
  • 218,885
  • 19
  • 262
  • 358
pyigal
  • 379
  • 5
  • 15
  • 1
    What have you done to try and solve the problem yourself so far? Where is the difficulty? Could you show us your code that you've tried to implement this with? – Derek Aug 17 '17 at 11:01
  • What exactly should be random? The number of elements (in your case 3) or the positions in the new array? Or which elements to pick from your array `x`? – MSeifert Aug 17 '17 at 11:03

2 Answers2

5

One approach would be -

# Get the indices of True values
idx = np.flatnonzero(x)

# Get unique indices of length 3 less than the number of indices and 
# set those in x as False
x[np.random.choice(idx, len(idx)-3, replace=0)] = 0

Sample run -

# Input array
In [79]: x
Out[79]: 
array([ True,  True, False, False, False,  True, False,  True,  True,
        True, False,  True,  True, False], dtype=bool)

# Get indices
In [80]: idx = np.flatnonzero(x)

# Set 3 minus number of True indices as False
In [81]: x[np.random.choice(idx, len(idx)-3, replace=0)] = 0

# Verify output to have exactly three True values
In [82]: x
Out[82]: 
array([ True, False, False, False, False, False, False,  True, False,
       False, False,  True, False, False], dtype=bool)
Divakar
  • 218,885
  • 19
  • 262
  • 358
0

Build an array with the number of desired True and False, then just shuffle it

import random
def buildRandomArray(size, numberOfTrues):
    res = [False]*(size-numberOfTrues) + [True]*numberOfTrues
    random.shuffle(res)
    return res

Live example

Netwave
  • 40,134
  • 6
  • 50
  • 93