Watch
Watch

Reputation: 72

how to modify a numpy matrix element-wise

I am currently trying to iterate over a matrix and modifying the elements inside it following some logic. I tried using the standard procedure for iterating matrices, but this only outputs the element at the current index, without updating the matrix itself.

This is what i have tried:

for row in initial_matrix:
    for element in row:
        if np.random.rand() > 0.5: element = 0
        print(element)

print(initial_matrix)

This, however, does not update initial matrix, I also tried:

for row in range(len(initial_matrix)):
    for element in range(row):
        if np.random.rand() > 0.5: initial_matrix[row, element] = 0
        print(element)

print(initial_matrix)

This is somehow working, but only in the lower diagonal of the matrix, while the upper remains unchanged. Here is the output:

0
0
1
0
1
2
0
1
2
3
[[1. 1. 1. 1. 1.]
 [0. 1. 1. 1. 1.]
 [1. 1. 1. 1. 1.]
 [0. 0. 1. 1. 1.]
 [0. 1. 1. 0. 1.]]

Upvotes: 0

Views: 877

Answers (3)

Laassairi Abdellah
Laassairi Abdellah

Reputation: 805

import numpy as np 
initial_matrix = np.ones([10,5])
print(initial_matrix)

for row in initial_matrix:
    for element in row:
        if np.random.rand() > 0.5: 
            element = 0
# Nothing will change
print(initial_matrix)

Basically you're not changing the values for the initial matrix with this approach

  [[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.]
     [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.]]

to better understand this let's take a simple example

initial_list=[1,1,1,1]

for i in initial_list:
    i=0

print(initial_list)

this will output the initial list as it is without any modifications because you're modifying the variable i and not the contents of the list itself, if you want to modify the list you can do something like this instead :

initial_list=[1,1,1,1]

for i in range(len(initial_list)):
    initial_list[i]=0

print(initial_list)

Now let's apply the same thing to your problem

    #Iterate through the rows and columns and change the initial matrix
    for i in range(initial_matrix.shape[0]):
        for j in range(initial_matrix.shape[1]):
            if np.random.rand() > 0.5: 
                initial_matrix[i,j] = 0
    print(initial_matrix)
[[0. 0. 0. 0. 0.]
 [0. 1. 1. 1. 0.]
 [0. 1. 0. 0. 1.]
 [0. 1. 0. 1. 1.]
 [1. 0. 1. 0. 1.]
 [0. 1. 1. 0. 0.]
 [0. 1. 0. 0. 1.]
 [1. 0. 0. 1. 0.]
 [1. 0. 0. 0. 0.]
 [0. 1. 0. 0. 0.]]

Upvotes: 2

constantstranger
constantstranger

Reputation: 9379

Here's a minimalist modification (UPDATED to use np.array throughout) to your code which will do what I believe you are asking:

import numpy as np
initial_matrix = np.array([
[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]])
for row in range(len(initial_matrix)):
    for element in range(len(initial_matrix[row])):
        if np.random.rand() > 0.5:
            initial_matrix[row, element] = 0
print(initial_matrix)

Output:

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

Here, I have assumed that you start with a matrix containing 1 in every position and that you want to change this to 0 where your random() criterion is met.

As you can see, an adjustment to the inner loop logic of your original code was helpful in getting this to work.

Upvotes: 1

user2736738
user2736738

Reputation: 30926

import numpy as np
a = np.random.rand(3,4)
print(a)
b = np.random.rand(3,4) 
print(b)
a[ b > 0.5]=0
print(a)

a = a > 0.5
print(a.astype(int))

You can index into the array with boolean results like this. Output:

[[0.21577153 0.4810459  0.88036672 0.93817657]
 [0.48424368 0.88673521 0.26706288 0.47468637]
 [0.02435961 0.75210616 0.18391152 0.80976478]]
[[0.27385928 0.84570069 0.55326907 0.57076882]
 [0.11333208 0.26364198 0.26381841 0.57497278]
 [0.29163378 0.08612894 0.37857834 0.59921316]]
[[0.21577153 0.         0.         0.        ]
 [0.48424368 0.88673521 0.26706288 0.        ]
 [0.02435961 0.75210616 0.18391152 0.        ]]
[[0 0 0 0]
 [0 1 0 0]
 [0 1 0 0]]

If you want to output boolean array in terms of integers you can use astype() function.

Upvotes: 0

Related Questions