NeuralNew
NeuralNew

Reputation: 116

Randomly zero-out certain percentage of rows in a matrix in python

Let's say I have matrix that contains 5 rows and 4 columns:

arr = [[1,1,1,1],
       [2,2,2,2],
       [3,3,3,3],
       [4,4,4,4],
       [5,5,5,5]]

and I want to randomly zero=out/mask a certain percentage of this matrix row-wise. So if I set the percentage to be zeroed to 40%. I will get the following:

arr = [[0,0,0,0],
       [2,2,2,2],
       [3,3,3,3],
       [0,0,0,0],
       [5,5,5,5]]

what would be a good way to achieve this? Thanks!

Upvotes: 1

Views: 508

Answers (4)

Arty
Arty

Reputation: 16737

One way to achieve your task is following (set num_zero_rows):

Try it online!

import random

arr = [[1,1,1,1],
       [2,2,2,2],
       [3,3,3,3],
       [4,4,4,4],
       [5,5,5,5]]

num_zero_rows = 2
zero_idxs = set(random.sample(range(len(arr)), num_zero_rows))
arr = [([0] * len(arr[i]) if i in zero_idxs else arr[i])
    for i in range(len(arr))]

print(arr)

Output:

[[0, 0, 0, 0], [2, 2, 2, 2], [0, 0, 0, 0], [4, 4, 4, 4], [5, 5, 5, 5]]

Or a bit shorter/cleaner/faster variant of same code:

Try it online!

import random

arr = [[1,1,1,1],
       [2,2,2,2],
       [3,3,3,3],
       [4,4,4,4],
       [5,5,5,5]]

num_zero_rows = 2

for i in random.sample(range(len(arr)), num_zero_rows):
    arr[i] = [0] * len(arr[i])

print(arr)

Upvotes: 2

ayandas
ayandas

Reputation: 2268

Simple. If your matrix has N rows, pick a list of indecies from [0, N-1]

inds = np.arange(N)
M = int(N * 40 / 100)  # 40% of rows
inds = np.random.choice(inds, M, replace=False) # without replacement

.. then just assign zeros to the specific rows and all columns

arr[inds, :] = 0.

Upvotes: 1

Shai
Shai

Reputation: 114786

You can sample an indicator vector using torch.bernouli:

torch.bernoulli(0.4 * torch.ones_like(arr[:, :1]))

Once you have this vector, you can multiply it with arr:

out = torch.bernoulli(0.4 * torch.ones_like(arr[:, :1])) * arr

And get the sampled array you want.

You should also look at dropout functions.

Upvotes: 1

anarchy
anarchy

Reputation: 5184

You can do this,

import random

arr = [[1,1,1,1],
       [2,2,2,2],
       [3,3,3,3],
       [4,4,4,4],
       [5,5,5,5]]

for i in arr:
    if random.randint(0, 1): # if 1 is hit, the entire line will zero out
        for j in range(len(i)):
            i[j] = 0

output try 1:

[[1, 1, 1, 1], 
[2, 2, 2, 2], 
[3, 3, 3, 3], 
[0, 0, 0, 0], 
[0, 0, 0, 0]]

output try 2:

[[0, 0, 0, 0], 
[2, 2, 2, 2], 
[0, 0, 0, 0], 
[0, 0, 0, 0], 
[5, 5, 5, 5]]

Upvotes: 0

Related Questions