Skip to content

← Indexing and Selection step 6 of 9

Medium Primitives

The value at the argmax

Jump to the task

Use one tensor to choose a column and another to supply the value at that column. Each row makes its own choice.

import torch

scores = torch.tensor([[1.0, 9.0, 3.0], [7.0, 2.0, 5.0]])
other = torch.tensor([[10.0, 20.0, 30.0], [70.0, 80.0, 90.0]])
idx = scores.argmax(dim=1, keepdim=True)
print(idx.tolist())                    # [[1], [0]]
print(other.gather(1, idx).tolist())    # [[20.0], [70.0]]

The result uses columns 1 and 0 from the two rows. Taking the maximum of other would produce [30.0, 90.0], which ignores the choices from scores.

Keep an index dimension for gather

For this two-dimensional input, gather needs a two-dimensional index tensor. An index of shape (rows, 1) requests one column from each row, and the gathered result has the same shape as that index.

Using argmax(dim=1) without keepdim=True gives shape (rows,), which gather rejects because its rank differs from the input's. Preserve that axis for gathering, then remove it from the result:

selected = other.gather(1, idx).squeeze(1)
print(selected.tolist())  # [20.0, 70.0]

Squeeze dimension 1 specifically so a batch with one row still returns a one-dimensional tensor. torch.take_along_dim(other, idx, dim=1) also works for these matching shapes.

This pattern can look up a value for a greedily selected class or action. If an action was sampled or supplied externally, use its actual index instead of recomputing an argmax.

Your task

def value_at_best(scores: torch.Tensor, other: torch.Tensor) -> torch.Tensor

Both tensors have shape (rows, columns), with at least one column and finite scores. Return shape (rows,): each entry is the value from other at that row's highest-scoring column in scores. On a score tie, choose the first matching column.