2

I have a two-dimensional numpy array of data, holding symmetric information about pairs of elements I'm tracking, very much like a round-robin bracket in a tournament. Keeping with that analogy, each player occupies one row with the column data being their score against a given opponent. For "legacy" reasons, all scores will be positive numbers except for the score against oneself, which will be 0.

Let's say I want to find the worst score of a given player, returning both the score and the opponent they played for that score. How might I do this?

The mediocre version might look like:

minimum = float('inf')
min_opp = None
for opponent_id in player_ids:
    if opponent_id != player_id:
        score = match_matrix[player_id, opponent_id]
        if score < minimum:
            minimum = score
            min_opp = opponent_id
return minimum, min_opp

But that's not using the power of numpy at all. I feel like there should be an easy solution, but I cannot seem to find it.

score = np.min(match_matrix[player, :])

gives the self-score, and I can't quite make the code from this answer work correctly.

Thanks!

EDIT: This answer provides good ideas, but only gets the minimum of the entire array, not a single row.

3
  • Does this answer your question? Commented Feb 1, 2017 at 17:05
  • Possible duplicate of Minimum of Numpy Array Ignoring Diagonal Commented Feb 1, 2017 at 17:09
  • 1
    @jotasi. That answers the question for an entire matrix, not for a row-by-row case. I wouldn't consider it a dupe. Commented Feb 1, 2017 at 17:13

2 Answers 2

2

You can select the given row, mask out the self-score and return the minimum of the remainder. Basically what you did but with an extra masking step. I would also recommend using np.argmin instead of np.min because it returns the index of the minimum, which is much more informative in this case:

mask = np.ones(match_matrix.shape(1), dtype=np.bool)
mask[player] = False
opponent = np.argmin(match_matrix[player, mask])
if opponent >= player:
    opponent += 1
score = match_matrix[player, opponent]
Sign up to request clarification or add additional context in comments.

1 Comment

Okay! That's readable and does what I need it to. Thanks so much.
0

Here's one way to do it. np.min() will give you the minimum value in a row, and np.where can tell you where that value is.

grid = np.random.randint(0,10,[5,5]) #Random matchups of 5x5 players
player = 1
low_score = np.min(grid[player][grid[player]>0])    #Only look at positive scores
opponent = np.where(grid[player]==low_score)[0]

Here, opponents will be an array of opponents, in case player got the same low score against multiple opponents.

1 Comment

argmin + indexing is probably more efficient than min + where.

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.