Fat Wallets
Fat Wallets

Reputation: 101

Numpy calculate Min Max in random 2D or 1D array

I'm trying to get a sum of Min or Max value in each row. If the number on first index is bigger than 12, return the max number in the row, else return min number in the row. Note that in below given sample, it's a 4 x 3 2D array. However I want my code to work given any array size or shape.

import numpy as np

arr = np.array([[11, 12, 13],
                [14, 15, 16],
                [17, 15, 11],
                [12, 14, 15]])

i_max = np.amax(arr,axis=1)
i_min = np.amin(arr,axis=1)
print(i_max)
print(i_min)

So far I can only get to the Min or Max number in each row using amax and amin. What I'm lacking is to access first value in each row and use if else statement to compare the size to 12. Can anyone give a hint.

The correct output for given sample should be 11 + 16 + 17 + 12 = 56

Upvotes: 2

Views: 320

Answers (2)

Ehsan
Ehsan

Reputation: 12407

You are almost there. You can create a mask (whatever you desire, here is first element of each row greater than 12) and calculate your operation as below. This is easily extendable to multi-dimensional array by changing the axis in min/max and your desired mask condition:

mask=arr[:,0]>12
(arr.max(1)*mask + arr.min(1)*~mask).sum()

output:

56

Comparison:

def m1(arr):
  mask=arr[:,0]>12
  return (arr.max(1)*mask+arr.min(1)*~mask).sum()

#@Dieter's solution
def m2(arr):
  return np.where(arr[:,0] > 12, np.max(arr, axis=1), np.min(arr, axis=1)).sum()
 
in_ = [np.random.randint(100, size=(n,n)) for n in [10,100,1000,10000]]

Runtime: m1 seems a tad faster, however, they converge to same performance in larger arrays.enter image description here

Upvotes: 1

Dieter
Dieter

Reputation: 2659

np.where contains 3 inputs.
The first one is your condition [ False, True, True False ...]
The second and third inputs, are the possible values.

Thus, if the condition is True, grep the value of the second input
otherwise, take the value of the third input.

np.where(arr[:,0] > 12, np.max(arr, axis=1), np.min(arr, axis=1))

return: array([11, 16, 17, 12])

and if you need the sum, just add sum :) :

np.where(arr[:,0] > 12, np.max(arr, axis=1), np.min(arr, axis=1)).sum()

return: 56

another way to represent it is like: [xv if c else yv for c, xv, yv in zip(condition, x, y)]

or just read the documentation: https://numpy.org/doc/stable/reference/generated/numpy.where.html :)

Upvotes: 1

Related Questions