fgadev
fgadev

Reputation: 21

Python trying to update a value in a 2D numpy array, value doesn't update

Sorry I'm a python noob.

I've been trying to find the max value in an 2D array representing x,y values.

The max value should then be replaced by 0 and plotted. However i have tried many ways to replace the value and i cant get the value replaced.

My code so far is

m2= [ [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] , [ 0 , 1 , 2 , 3 , 2 , 1 , 0 , 1 , 2 , 3 ]]

a2 = np.array(m2, dtype=np.int)

plt.plot(a2[0,:], a2[1,:], 'r-x')

a2maxy = np.max(a2[1,:])
print("a2 y values: ", a2[1,:])

for y in (a2[1,:]):
    if (y==a2maxy):
        print(y)
        print("max found ", y)
        y=0
        print(y)

But my output (showing the max y value as unchanged is

a2 y values:  [0 1 2 3 2 1 0 1 2 3]
3
max found  3
0
3
max found  3
0
[[0 1 2 3 4 5 6 7 8 9]
 [0 1 2 3 2 1 0 1 2 3]]

Upvotes: 2

Views: 344

Answers (2)

pkuderov
pkuderov

Reputation: 3551

The given answer by @lydiash is correct. But, as you're new to numpy, I'd like to also give you some insights about what's the point of using numpy :)

Let's simplify your code a bit. I see that a2 contains all data for a plot. But first row, denoting x values, is needed only for plotting, and you're working only with actual y values. So, let's split them!

xs = np.arange(10) # gives you exactly [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ]
ys = np.array([ 0 , 1 , 2 , 3 , 2 , 1 , 0 , 1 , 2 , 3 ])

plt.plot(xs, ys, 'r-x')
print(f'y values: {ys}') # prints "y values:  [0 1 2 3 2 1 0 1 2 3]"

In the second part you're looking for max y value and change it to zero. You can do it in a for loop, of course. But also you could make use of power of numpy - vector operations!

As you've calculated the max value with y_max = np.max(ys) (which also can be written as y_max = ys.max()), you can directly change ys in one hop:

y_max = ys.max()
print(f'max value found: {y_max}')  # prints "max value found: 3"

ys[ys == y_max] = 0  # here the changing of max values to zero happens!
print(f'new y values: {ys}') # prints "new y values:  [0 1 2 0 2 1 0 1 2 0]"

Expression ys == y_max is kinda a filter on all indices of ys - only indices of matched values are taken.


Optional clarification: If you want to understand ys == y_max part better, just print what it gives:

print(ys == y_max)
# prints "[False False False True False False False False False True]"
# as you see, `True` values are exactly at positions of maximum value

It gives you a mask on all indices of the array. And you can use it further as some sort of filter - ys[mask] returns only values filtered by that mask.

Upvotes: 1

lydiash
lydiash

Reputation: 85

I think your problem is that you're not actually referencing the array of values you want to edit in the for loop. There's probably a slicker way to do this, but you can do what you want with enumerate as the iterator in the for loop, and then referencing the item in the a2 array you care about, like so:

import numpy as np
from matplotlib import pyplot as plt
m2= [ [ 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] , [ 0 , 1 , 2 , 3 , 2 , 1 , 0 , 1 , 2 , 3 ]]

a2 = np.array(m2, dtype=np.int)

plt.plot(a2[0,:], a2[1,:], 'r-x')

a2maxy = np.max(a2[1,:])
print("a2 y values: ", a2[1,:])

for idx,y in enumerate(a2[1,:]):
    if (y==a2maxy):
        print("max found ", y)
        a2[1,idx]=0

print("new a2 y values: ", a2[1,:])

and the output is now:

a2 y values:  [0 1 2 3 2 1 0 1 2 3]
max found  3
max found  3
new a2 y values:  [0 1 2 0 2 1 0 1 2 0]

Upvotes: 1

Related Questions