Home > database >  How to randomly edit elements in a 2D array?
How to randomly edit elements in a 2D array?

Time:09-30

I have a 2D NumPy array in which I would like to randomly replace a few data points with different values. How do to do that for a general NumPy 2D array?

Example: Randomly replace 6 data elements of A having value 1 with value 2.

Input-
A = [
    [1,1,1,1,1,0,0,1,1],
    [1,0,1,0,1,1,0,1,1],
    [0,1,1,1,1,1,1,1,0],
    [1,1,1,1,1,0,0,1,1],
    [1,1,0,0,1,0,0,1,1],
    [1,1,1,1,1,0,0,1,1],
    ]

Output-
A'= [
    [1,1,1,2,1,0,0,1,2],
    [1,0,1,0,1,1,0,1,1],
    [0,1,1,1,1,1,1,1,0],
    [1,1,1,2,1,0,0,1,1],
    [1,1,0,0,1,0,0,1,2],
    [2,1,1,1,1,0,0,1,2],
    ]

How to achieve this using Numpy with few lines of code? Any help would be appreciated.

CodePudding user response:

You can get a random position of an element in your array and, if the value is 1, replace it with 2.

Here an example:

from random import randint

A = [
    [1,1,1,1,1,0,0,1,1],
    [1,0,1,0,1,1,0,1,1],
    [0,1,1,1,1,1,1,1,0],
    [1,1,1,1,1,0,0,1,1],
    [1,1,0,0,1,0,0,1,1],
    [1,1,1,1,1,0,0,1,1],
    ]

arrayLenght = len(A)
rowLenght = len(A[0])

for _ in range(6):
    y = randint(0,arrayLenght-1)
    x = randint(0,rowLenght-1)

    while A[y][x] != 1:
        y = randint(0,arrayLenght-1)
        x = randint(0,rowLenght-1)
    
    A[y][x] = 2

print(A)

CodePudding user response:

So, break up what you are asking for into several steps. First, get the x and y coordinates where A has the value of 1:

>>> import numpy as np
>>> A = np.array([
...     [1,1,1,1,1,0,0,1,1],
...     [1,0,1,0,1,1,0,1,1],
...     [0,1,1,1,1,1,1,1,0],
...     [1,1,1,1,1,0,0,1,1],
...     [1,1,0,0,1,0,0,1,1],
...     [1,1,1,1,1,0,0,1,1],
...     ])
>>> x, y = np.where(A == 1)
>>> x
array([0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3,
       3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5])
>>> y
array([0, 1, 2, 3, 4, 7, 8, 0, 2, 4, 5, 7, 8, 1, 2, 3, 4, 5, 6, 7, 0, 1,
       2, 3, 4, 7, 8, 0, 1, 4, 7, 8, 0, 1, 2, 3, 4, 7, 8])

Then, randomly sample from these coordinates. We'll accomplish this by selecting a random sample of the indices of the indices:

>>> random_idx = np.random.choice(np.arange(len(x)), 6)
>>> random_idx
array([31, 24, 38, 14, 10, 17])

Then, use this to do a bulk assignment to the value 2 at those indices:

>>> A
array([[1, 1, 1, 1, 1, 0, 0, 1, 1],
       [1, 0, 1, 0, 1, 1, 0, 1, 1],
       [0, 1, 1, 1, 1, 1, 1, 1, 0],
       [1, 1, 1, 1, 1, 0, 0, 1, 1],
       [1, 1, 0, 0, 1, 0, 0, 1, 1],
       [1, 1, 1, 1, 1, 0, 0, 1, 1]])
>>> A[x[random_idx], y[random_idx]] = 2
>>> A
array([[1, 1, 1, 1, 1, 0, 0, 1, 1],
       [1, 0, 1, 0, 1, 2, 0, 1, 1],
       [0, 1, 2, 1, 1, 2, 1, 1, 0],
       [1, 1, 1, 1, 2, 0, 0, 1, 1],
       [1, 1, 0, 0, 1, 0, 0, 1, 2],
       [1, 1, 1, 1, 1, 0, 0, 1, 2]])

So, all in one:

import numpy as np
A = np.array([
    [1,1,1,1,1,0,0,1,1],
    [1,0,1,0,1,1,0,1,1],
    [0,1,1,1,1,1,1,1,0],
    [1,1,1,1,1,0,0,1,1],
    [1,1,0,0,1,0,0,1,1],
    [1,1,1,1,1,0,0,1,1],
    ])

x, y = np.where(A == 1)
random_idx = np.random.choice(np.arange(len(x)), 6)

A[x[random_idx], y[random_idx]] = 2

CodePudding user response:

I think this is the solution you were looking for. Use size to get the number of elements in the array. Use A.item(position) to get the value in a position. Use A.itemset(posizione, value) to set value in position.

Here the code:

from random import randint
from numpy import *


A = matrix([
    [1,1,1,1,1,0,0,1,1],
    [1,0,1,0,1,1,0,1,1],
    [0,1,1,1,1,1,1,1,0],
    [1,1,1,1,1,0,0,1,1],
    [1,1,0,0,1,0,0,1,1],
    [1,1,1,1,1,0,0,1,1],
    ])

s = size(A)

for _ in range(6):
    position = randint(0,s)

    while A.item(position) != 1:
        position = randint(0,s)
    
    A.itemset(position,2)

print(A)

Important: the array must me matrix for it to work.

  • Related