2

Consider this 2D array:

import numpy as np
a = np.array([[3,1,5,3],[1,4,8,2],[4,2,1,2],[9,2,4,4]])

I know how to find the maximum entry of each row: np.amax(a, axis=1). This returns array([5,8,4,9])

What I would like to do, however, is to get the maximum entry of each row after a certain index n, i.e. ignoring the first n terms and just looking for the maximum amongst the remaining entries in that row, for each row.

One complication: the point at which I "slice" each row is different for each row.

Example: I want to calculate the maximum of each row, but only amongst the last 2 entries in the first row, the last 3 entries in the second row, the last 2 in the third row, and the last 1 in the fourth row. This should return array([5,8,2,4])

If this can be done without for or while loops, that would be great -- I really cannot use them due to computational time limits.

1
  • @Prune that just prints [5,8,4,9] for n=0, [8,4,9] for n=1, [4,9] for n=2, etc Commented Sep 12, 2019 at 0:28

4 Answers 4

1

You can use list comprehension.

   import numpy as np
   a = np.array([[3,1,5,3],[1,4,8,2],[4,2,1,2],[9,2,4,4]])
   inds = [-2,-3,-2,-1] # the indices in your example

   result = [max(line[i:]) for line,i in zip(a,inds)]
   print(result)
   #output
   [5, 8, 2, 4]
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! The only thing stopping me from approving this question is the for loop, I really cannot afford using many in my code and I'm already using a couple elsewhere. I am dealing with very large arrays and a lot of iterations...
1

You can set the undesired entries to a value smaller than the minimum in your array and take the rowwise maximum value afterwards:

starts = np.array([2, 1, 2, 3])
mask = np.arange(a.shape[1]) < starts[:, None]
a[mask] = np.min(a) - 1
# array([[0, 0, 5, 3],
#        [0, 4, 8, 2],
#        [0, 0, 1, 2],
#        [0, 0, 0, 4]])
np.amax(a, axis=1)
# array([5, 8, 2, 4])

Comments

0

You could create a mask like in this answer:

a = np.array([[3,1,5,3],[1,4,8,2],[4,2,1,2],[9,2,4,4]])
n = np.array([2,3,2,1])
idx = a.shape[1]-n  #starting indices
mask=np.arange(a.shape[1]) >= idx[:,None]

# array([[False, False,  True,  True],
#       [False,  True,  True,  True],
#       [False, False,  True,  True],
#       [False, False, False,  True]])

Then apply reduceat with maximum over masked array:

n = np.roll(n,1) #indices for slices
n[0] = 0 #starts at zero

np.maximum.reduceat(a[mask],n.cumsum())
array([5, 8, 2, 4], dtype=int32)

Comments

0

can also mask / filter the array then find row-wise maximums like this:

row_limits = a.shape[1]-np.array([[2],[3],[2],[1]]) 
idx = np.repeat(np.arange(0,a.shape[1]), a.shape[0], 0).reshape(a.shape).T 
mask = idx >= row_limits
result = np.amax(np.multiply(a,mask),axis=1) 

output:

array([5, 8, 2, 4])

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.