Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find elements loactions is numpy array [closed]

I have a 2D array, from which I want to get the indices of every element that is in the top 2 values both in it's row and in it's column. For example, given the following array -

r = np.random.rand(5,5)
>>> r
array([[ 0.89771084,  0.84415435,  0.81601728,  0.42322215,  0.78240944],
       [ 0.84490939,  0.53644975,  0.3506268 ,  0.98212093,  0.76426087],
       [ 0.254155  ,  0.12818165,  0.82656036,  0.97441244,  0.58597015],
       [ 0.50566688,  0.67774518,  0.58434845,  0.5204808 ,  0.9225643 ],
       [ 0.73930611,  0.31890204,  0.47691016,  0.28034347,  0.57832287]])

The required output is -

[[0,0],
 [1,0],
 [0,1],
 [3,1],
 [2,2],
 [1,3],
 [2,3],
 [3,4]]

Notice [0,2] is left out, because although it is the second largest element of it's columns, it is the third largest element of it's row.

like image 897
proton Avatar asked Mar 12 '26 20:03

proton


1 Answers

As suggested in the comments, argsort is the key. It gives you the indices of the sorted elements. Performing argsort twice gives you the rank. (There is a more efficient way to obtain the ranks, which I evilly leave as an exercise.)

Then use the ranks along rows and columns to identify elements that are in the top 2 for both, ranks and columns.

Example implementation:

import numpy as np

r = np.array([[ 0.89771084,  0.84415435,  0.81601728,  0.42322215,  0.78240944],
              [ 0.84490939,  0.53644975,  0.3506268 ,  0.98212093,  0.76426087],
              [ 0.254155  ,  0.12818165,  0.82656036,  0.97441244,  0.58597015],
              [ 0.50566688,  0.67774518,  0.58434845,  0.5204808 ,  0.9225643 ],
              [ 0.73930611,  0.31890204,  0.47691016,  0.28034347,  0.57832287]])

# indices of elements in descending order
col_order = np.argsort(r, axis=0)[::-1, :]
row_order = np.argsort(r, axis=1)[:, ::-1]

# sorting the indices gives the rank (0=highest element, 4=lowest element)
col_rank = np.argsort(col_order, axis=0)
row_rank = np.argsort(row_order, axis=1)

# mark top n elements in each row and column
n = 2
col_top_n = col_rank < n
row_top_n = row_rank < n

# mark elements that are in the nop n of BOTH, a row and a column
both_top_n = np.logical_and(row_top_n, col_top_n)

# get indices of marked elements
row_indices, col_indices = np.nonzero(both_top_n)

print('The following elements are in the top {} of both their rows and columns:'.format(n))
for row, column in zip(row_indices, col_indices):
    print('row: {}, column: {}, value: {}'.format(row, column, r[row, column]))
like image 60
MB-F Avatar answered Mar 14 '26 08:03

MB-F



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!