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

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!

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

Shirink the numpy array with max

I have numpy array such as np.array([2,2])
[[1,9],
[7,3]]
I want to get the max of third demention and make this into one dimension.
then numpy.array should be like this [9,7]
I think I can do this with for loop and make another numpy.
However it looks ackword, is there any good way to do this ?
amax function (alias is np.max)
import numpy as np
a = np.array([[1,9],
[7,3]])
np.amax(a, axis=1)
# array([9, 7])
Use max with specific axis. In this example axis is 1.
import numpy as np
arr = np.array([[1,9],
[7,3]])
arr_max = np.max(arr, axis=1)
print(arr_max)
Output:
[9 7]
numpy.max is just an alias for numpy.amax. This function only works on a single input array and finds the value of maximum element in that entire array (returning a scalar). Alternatively, it takes an axis argument and will find the maximum value along an axis of the input array (returning a new array).
import numpy
np_array = numpy.array([[1,9],
[7,3]])
max_array = numpy.max(np_array, axis=1)
print(max_array.shape)
print(max_array)
Output:
(2,)
[9 7]

How to find index and max value for overlapping numpy arrays

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)]))

Multi-dimensional filtering using scipy.ndimage_generic_filter

I would like to use a generic filter to calculate the mean of values within a given window (or kernel), for values that fulfill a couple of conditions. I expected the following code to produce a mean filter of the first array in a 3-layer window, using the other two arrays to mask values from the mean calculation.
from scipy import ndimage
import numpy as np
#some test data
tstArr = np.random.rand(3,7,7)
tstArr = tstArr*10
tstArr = np.int_(tstArr)
tstArr[1] = tstArr[1]*100
tstArr[2] = tstArr[2] *1000
#mean function
def testFun(tstData,processLayer,nLayers,kernelSize):
funData= tstData.reshape((nLayers,kernelSize,kernelSize))
meanLayer = funData[processLayer]
maskedData = meanLayer[(funData[1]>1)&(funData[2]<9000)]
returnMean = np.mean(maskedData)
return returnMean
#number of layers in the array
nLayers = np.shape(tstArr)[0]
#window size
kernelSize = 5
#create a sampling window of 5x5 elements from each array
footprnt = np.ones((nLayers,kernelSize,kernelSize),dtype = np.int)
# calculate the mean of the first layer in the array (other two are for masking)
processLayer = 0
tstOut = ndimage.generic_filter(tstArr, testFun, footprint=footprnt, extra_arguments = (processLayer,nLayers,kernelSize))
I thought this would yield a 7x7 array of masked mean values from the first layer in the input array. The output is a 3x7x7 array, and I don't understand what the values represent. I'm not sure how to produce the "masked" mean-filtered array, or how to interpret the output as given.
Your code produce a mean filter of the first array in a 3-layer window, using the over two arrays to mask values from the mean calculation. You will find the result in tstOut[1].
What is going on ? When you call ndimage.generic_filter with tstArr of shape (3, 7, 7) and footprint=np.ones((3, 5, 5)) then for all i from 0 to 2, for all j from 0 to 6 and for all k from 0 to 6, testFun is called with the subarray of tstArr centered in (i, j, k) and of shape (3, 5, 5) (the array is reflected at the boundary to supply missing values).
In the end:
tstOut[0] is the mean filter of tstArr[0] with tstArr[0] and tstArr[1] as masks
tstOut[1] is the mean filter of tstArr[0] with tstArr[1] and tstArr[2] as masks
tstOut[2] is the mean filter of tstArr[1] with tstArr[2] and tstArr[2] as masks
Again, the wanted result is in tstOut[1].
I hope this will help you.

How to search in one NumPy array for positions for getting at these position the value from a second NumPy array?

I have two raster files which I have converted into NumPy arrays (arcpy.RasterToNumpyArray) to work with the values in the raster cells with Python.
One of the raster has two values True and False. The other raster has different values in the range between 0 to 1000. Both rasters have exactly the same extent, so both NumPy arrays are build up identically (columns and rows), except the values.
My aim is to identify all positions in NumPy array A which have the value True. These positions shall be used for getting the value at these positions from NumPy array B.
Do you have any idea how I can implement this?
If I understand your description right, you should just be able to do B[A].
You can use the array with True and False values to simply index into the other. Here's a sample:
import numpy as np
a = np.array([[1,2,3],[4,5,6],[7,8,9]])
b = np.array([[True,False,False],[False,True,False],[False,False,True]])
a[b] ## gives array([1, 5, 9])

Categories

Resources