Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's a more efficient way to calculate the max of each row in a matrix excluding its own column?

Tags:

python

numpy

For a given 2D matrix np.array([[1,3,1],[2,0,5]]) if one needs to calculate the max of each row in a matrix excluding its own column, with expected example return np.array([[3,1,3],[5,5,2]]), what would be the most efficient way to do so? Currently I implemented it with a loop to exclude its own col index:

n=x.shape[0]
row_max_mat=np.zeros((n,n))
rng=np.arange(n)
for i in rng:
  row_max_mat[:,i] = np.amax(s_a_array_sum[:,rng!=i],axis=1)

Is there a faster way to do so?

like image 754
santoku Avatar asked Apr 30 '20 18:04

santoku


2 Answers

Similar idea to yours (exclude columns one by one), but with indexing:

mask = ~np.eye(cols, dtype=bool)
a[:,np.where(mask)[1]].reshape((a.shape[0], a.shape[1]-1, -1)).max(1)

Output:

array([[3, 1, 3],
       [5, 5, 2]])
like image 151
Quang Hoang Avatar answered Nov 15 '22 16:11

Quang Hoang


You could do this using np.accumulate. Compute the forward and backward accumulations of maximums along the horizontal axis and then combine them with an offset of one:

import numpy as np

m = np.array([[1,3,1],[2,0,5]])

fmax = np.maximum.accumulate(m,axis=1)
bmax = np.maximum.accumulate(m[:,::-1],axis=1)[:,::-1]

r = np.full(m.shape,np.min(m))
r[:,:-1] = np.maximum(r[:,:-1],bmax[:,1:])
r[:,1:]  = np.maximum(r[:,1:],fmax[:,:-1])

print(r)

# [[3 1 3]
#  [5 5 2]]

This will require 3x the size of your matrix to process (although you could take that down to 2x if you want an in-place update). Adding a 3rd&4th dimension could also work using a mask but that will require columns^2 times matrix's size to process and will likely be slower.

If needed, you can apply the same technique column wise or to both dimensions (by combining row wise and column wise results).

like image 2
Alain T. Avatar answered Nov 15 '22 14:11

Alain T.