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]]
-
1Does this answer your question? Generating/Placing k random items in a 2d arrayPeter O.– Peter O.2020-04-14 02:43:53 +00:00Commented 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.sara kaviani– sara kaviani2020-04-14 02:49:43 +00:00Commented Apr 14, 2020 at 2:49
-
1The 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.sara kaviani– sara kaviani2020-04-14 02:57:11 +00:00Commented Apr 14, 2020 at 2:57
Add a comment
|
2 Answers
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.
2 Comments
Susmit Agrawal
Since sampling is with replacement, the probability of that happening is very low. But it is statistically possible.
Susmit Agrawal
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.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