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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.