For a matrix, I want to get the row (if it exists) which has the lesser values for each column - strictly dominated by all other rows. For example,
A = [[7,5,8,2]
[10,3,7,8]
[6,2,6,1]]
B = [[7,5,8,2]
[10,3,7,8]
[9,5,6,7]
[6,2,6,1]]
For matrix A, row [6,2,6,1]
has the minimum values. A[2][i] < A[1][i] and A[2][i] < A[0][i] for all values of i. So, its index should be returned.
For matrix B, no row with the lowest values exists (6 in column 2 is not less than other values in that column).
Is there a cleaner way to do that, other than to loop each column individually?
CodePudding user response:
Here you go. See the comments for what each line does.
import numpy as np
def get_index_of_minimum_row(arr):
""" returns the index of the minimum row or None if it does not exist """
#Get the minimum value of each column.
column_minimums = arr.min(axis=0)
#Create a mask of the array for the minimum values (True where it is the minimum, False where it is not).
column_minimums_mask = arr <= column_minimums
#Ensure that the minimum value is the only minimum value in its column.
has_only_one_minimum_per_column = column_minimums_mask.sum() == arr.shape[1]
if not has_only_one_minimum_per_column:
return None
#Ensure that all minimums are in the same row.
all_minimums_are_in_the_same_row = column_minimums_mask.all(axis=1)
if not all_minimums_are_in_the_same_row.any():
return None
#Get the index of the minimum row and return it
return np.squeeze(np.argwhere(all_minimums_are_in_the_same_row))
A = np.array([
[7,5,8,2],
[10,3,7,8],
[6,2,6,1],
])
B = np.array([
[7,5,8,2],
[10,3,7,8],
[9,5,6,7],
[6,2,6,1],
])
print(get_index_of_minimum_row(A)) #returns 2
print(get_index_of_minimum_row(B)) #returns None