How to find index and max value for overlapping numpy arrays - python

I have two numpy Array with the same SHAPEs. One with values and one with "zones". I need to find max value and index of the value in valuearr which overlap zone 3 in zonearr:
import numpy as np
valuearr = np.array([[10,11,12,13],
[21,22,23,24],
[31,32,33,34],
[41,42,43,44]])
zonearr = np.array([ [0,0,1,1],
[0,0,1,1],
[3,3,0,0],
[3,3,0,0]])
Im trying:
valuearr[np.argwhere(zonearr==3)].max()
44
When it should be 42.
To get index i try
ind = np.unravel_index(np.argmax(valuearr[np.argwhere(zonearr==3)], axis=None), valuearr.shape)
Which of course doesnt work since max value is not 44 and also give error:
builtins.ValueError: index 19 is out of bounds for array with size 16

You can use a masked array to do what you want.
With:
import numpy as np
valuearr = np.array([[10,11,12,13],
[21,22,23,24],
[31,32,33,34],
[41,42,43,44]])
zonearr = np.array([ [0,0,1,1],
[0,0,1,1],
[3,3,0,0],
[3,3,0,0]], dtype=np.int)
First mask out all the values where zonearr is not equal to 3:
masked = np.ma.masked_array(valuearr, mask = (zonearr!=3))
Then find the position of the maximum value with argmax:
idx_1d = np.argmax(masked)
Finally, convert it into a 2d index:
idx_2d = np.unravel_index(idx_1d, valuearr.shape)
and print:
print(idx_2d, valuearr[idx_2d])
which gives:
(3, 1) 42

Please try the below code
np.max(valuearr[np.where(zonearr==3)])
It fetches the indices of the elements from zonearr, where the value equals to '3'. Followed by, obtaining the maximum element from valuearr through the obtained indices.
To obtain the index of the element 42(as per your example), please use the below code:
np.argwhere(valuearr==np.max(valuearr[np.where(zonearr==3)]))

Related

Changing the value of values after a particular index along one axis in a 3D numpy array

I have a 3d array of format given below.
The below is the one sample of the 3D array, like it , it contain more than 1000.
sample
shape of the 3D array is (1000 x 10 x 5)
The image contain one element (10 x 5)
I want to change the value to 0 after the 3rd one on the last value
check the figure below
desired
I want to change like it for all the 1000 elements in my array.
Is there a better way to do it other than using "for loop" ?
import numpy as np
# Your array here:
arr = np.arange(50000).reshape(1000, 10, 5)
# Solution:
arr[:, 3:, -1] = 0

Python: Broadcast 2D index array from argmin in a 3D array

I have a 3D grid with different values, and apply argmin along axis=2 to it, to get the lowest value in third dimension. How can I now extract the actual value and not only the index of the minimum value?
import numpy as np
input = np.random.normal(size=(30,40,10))
minvals = np.argmin(input,axis=2)
foo = input[minvals]
Minvals give my the index along axis 2 for the minimum value as expected. I expected, that foo gives my a 2D array with the actual minimum values, but foo is now a 4D array...
Try take_along_axis mixed with expand_dims. See the take_along_axis tutorial for more details:
import numpy as np
input = np.random.normal(size=(30,40,10))
minvals = np.argmin(input,axis=2)
foo = np.take_along_axis(input, np.expand_dims(minvals, axis=2), axis=2).reshape(30,40)
# Verification
foo_2 = np.min(input,axis=2)
print('Good result!' if np.allclose(foo,foo_2) else 'Bad results')
Ouput:
% python3 script.py
Good result!

How to change numpy array based on mask array?

I have an array data_set, size:(172800,3) and mask array, size (172800) consists of 1's and 0's. I would like to replace value form data_set array based on values (0 or 1) in mask array by the value defined by me: ex : [0,0,0] or [128,16,128].
I have tried, "np.placed" function but here the problem is the incorrect size of mask array.
I have also checked the more pythonic way:
data_set[mask]= [0,0,0] it worked fine but for some raison only for 2 first elements.
data_set[mask]= [0,0,0]
data_set = np.place(data_set, mask, [0,0,0])
My expected output is to change the value of element in data_set matrix to [0,0,0] if the mask value is 1.
ex.
data_set = [[134,123,90] , [234,45,65] , [32,233,45]]
mask = [ 1, 0, 1]
output = [[0,0,0] , [234, 45,65] , [0,0,0]]
When you try to index your data with mask numpy assumes you are giving it a list of indices. Use boolean arrays, or convert your mask to a list of indices:
import numpy as np
data_set = np.array([[134,123,90] , [234,45,65] , [32,233,45]])
mask = np.array([1, 0, 1])
val = np.zeros(data_set.shape[1])
data_set[mask.astype(bool),:] = val
# or
data_set[np.where(mask),:] = val
The first one converts your array of ints to an array of bools, while the second one creates a list of indexes where the mask is not zero.
You can set val to whatever value you need as long as it matches the remaining dimension of the dataset (in this case, 3).

extracting ith and ith+1 from random 2D numpy array

I have a numpy array consisting of
[1,3,8,6,0,2,4,5,9,7]
This array is a random array consisting of 10 numbers 0-9.
I also have a 2D numpy array, a 10X10 2D numpy array with numerical values.
I would like to use my 1D numpy array (above) to access specific instances in my 2D numpy array, by looping through the 1D array
Loop 1: takes in 1 and 3, and finds the value at [1:3] in my 2D numpy array.
Loop 2: takes in 3 and 8, and finds the value at [3:8] in my 2D numpy array.
.
Loop 10: takes in 7 and 1, and finds the value at [7:1] in my 2D numpy array.
I would like to add up these values in my 2D numpy array.
so far I have :
array=[1,3,8,6,0,2,4,5,9,7]
values =0
for i in range (0, len(array)): #this is 10
a=array2[i,array[i]+1] #array2 is the 2D numpy array with the values
values=values+a
This works to some degree but how to I get it to access the last element to the first? i.e. find [7,1]
You can use simple slicing to make this work.
arr = np.random.randint(0, 10, (10,10))
pos = np.array([1,3,8,6,0,2,4,5,9,7])
pos = np.append(pos, pos[0])
rows = pos[0:-1]
cols = pos[1:]
result = sum(arr[rows, cols])
You can do the slicing twice to make it work.
values = 0
for i in range(len(array)):
a = Matrix[array[i],array[i+1]]
values += a
Also, the array you put has 11 elements which means the 10-th loop will not be what you intended.
I'm not sure I fully understood what you were trying to achieve but...
What about something like this?
a = np.array([1,3,8,6,0,9,2,4,5,9,7])
b = np.array(range(100)).reshape(10,10)
for i in range (len(a)):
print (a[i%len(a)],a[(i+1)%len(a)])
print (b[a[i%len(a)],a[(i+1)%len(a)]])
I removed 10 from the a array to avoid an index out of range error.
I also took the value [x,y] (and not the range [x:y] from the 2D array.

how to use values of a pandas DataFrame as numpy array index

I have a pandas dataFrame like this.
The X, Y, Z are they (x,y,z) coordinates that represent a point inside a cube of side-length 255.
I want to create a numpy array/dataFrame from this, whose index will be the (x,y,z) coordinates and value is the intensity.
the output should be
data[133,55,250] = 8
data[133,61,254] = 21
...
I tried something like this
data = np.zeros((255,255,255), dtype=np.int)
index = np.array((temp['X'], temp['Y'], temp['Z']))
but returned index is a (3,15) array.
I want a index where
data[index] = intensity
will give me my result.
Instead of
index = np.array((temp['X'], temp['Y'], temp['Z']))
you could use integer array indexing to perform the assignment:
data = np.zeros((256, 256, 256), dtype=np.int)
data[temp['X'], temp['Y'], temp['Z']] = temp['intensity']

Categories

Resources