0

I have a 2D-matrix of some numbers and I want to randomly change a fraction of the non-zero members (e.x. 0.2) to become zero and then again randomly choose equal to that fraction amount (0.2) between all zeroes and give them random numbers. Is there any straight forward way to do that? for example: The original matrix is : x = [[1,2,3],[4,0,7],[2,10,0]] After first step (2 randomly selected numbers change to zero): x = [[1,0,0],[4,0,7],[2,10,0]] After second step (2 randomly selected zeros change to random numbers): x = [[1,0,5],[4,7,7],[2,10,0]]

3
  • 1
    Does this answer your question? Generating/Placing k random items in a 2d array Commented Apr 14, 2020 at 2:43
  • Not exactly. I want to know a straight forward codes with pandas or numpy. I know the algorithm and I have written some codes but it takes a lot of time. Commented Apr 14, 2020 at 2:49
  • 1
    The main problem is to randomly select some elements in a matrix and make them zero. I know how this can be done in 1D arrays with numpy.random.choice(). but it doesn't work for 2D arrays. Commented Apr 14, 2020 at 2:57

2 Answers 2

1

One method:

arr = np.ones((5, 5)) # Your matrix
print("Before Replacement")
print(arr)

# Number of elements to replace
num_replaced = 3 

# Random (x, y) coordinates
indices_x = np.random.randint(0, arr.shape[0], num_replaced)
indices_y = np.random.randint(0, arr.shape[1], num_replaced)

arr[indices_x, indices_y] = 0
print("After replacement")
print(arr)
 

Sample Output:

Before Replacement

[[1. 1. 1. 1. 1.]

[1. 1. 1. 1. 1.]

[1. 1. 1. 1. 1.]

[1. 1. 1. 1. 1.]

[1. 1. 1. 1. 1.]]

After replacement

[[0. 1. 1. 1. 1.]

[1. 0. 1. 1. 1.]

[1. 1. 1. 1. 1.]

[1. 0. 1. 1. 1.]

[1. 1. 1. 1. 1.]]

EDIT


You can use np.random.choice instead on np.random.randint as follows:

indices_x = np.random.choice(range(arr.shape[0]), num_replaced, replace=REPLACE)
indices_y = np.random.choice(range(arr.shape[1]), num_replaced, replace=REPLACE)

Here, you can easily switch between sampling with or without replacement.

Sign up to request clarification or add additional context in comments.

2 Comments

Since sampling is with replacement, the probability of that happening is very low. But it is statistically possible.
You can replace np.random.randint(0, arr.shape[0], num_replaced) with np.random.choice(range(arr.shape[0]), num_replaced, replace=False) for both axes to change this behaviour.
0

I would try to create a simple function for this. So you can input the number desired.

import pandas as pd
import random

def random_converter(dataframe, k, isZero=True, input_data='random_value'):
  # Copy df
  dataframe_local = dataframe.copy()

  if input_data=='random_value':
    input_data = random.randint(0,10)

  ki = 0
  while ki < k:
    row_selected = dataframe_local.sample(1).T

    # VERIFY CONDITION
    if isZero:
      attributes = row_selected[row_selected.iloc[:, 0] == 0]
    else:
      attributes = row_selected[row_selected.iloc[:, 0] != 0]

    # No zero in the row
    if attributes.size == 0:
      continue

    column_index = attributes.index
    row_index = attributes.columns
    dataframe_local.iloc[row_index, column_index] = input_data    

    ki += 0
  return dataframe_local

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.