Working with tensors in PyTorch involves frequently reading and updating specific elements, rows, columns, or slices of data. Whether you're preprocessing input data, inspecting model outputs, or manually adjusting weights, understanding how to access and modify tensor values is a fundamental skill.
This guide covers indexing, slicing, advanced indexing, and in-place modification of PyTorch tensors with practical examples.
Accessing Single Values with Indexing
Use square brackets with an index to access a specific element. PyTorch uses zero-based indexing, just like Python lists and NumPy arrays.
1D Tensor
import torch
tensor = torch.tensor([10, 20, 30, 40, 50])
print("First element:", tensor[0])
print("Third element:", tensor[2])
print("Last element:", tensor[-1])Output:
First element: tensor(10)
Third element: tensor(30)
Last element: tensor(50)Getting a Python Number from a Tensor
Accessing a single element returns a 0-dimensional tensor, not a plain Python number. Use .item() to extract the actual value:
import torch
tensor = torch.tensor([10, 20, 30])
element = tensor[1]
print(f"Type: {type(element)}, Value: {element}")
value = tensor[1].item()
print(f"Type: {type(value)}, Value: {value}")Output:
Type: <class 'torch.Tensor'>, Value: 20
Type: <class 'int'>, Value: 202D Tensor (Matrix)
For multi-dimensional tensors, provide an index for each dimension:
import torch
matrix = torch.tensor([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print("matrix[1, 2]:", matrix[1, 2].item())
print("matrix[1][2]:", matrix[1][2].item())Output:
matrix[1, 2]: 6
matrix[1][2]: 6Accessing Multiple Values with Slicing
Slicing uses the start:stop:step syntax to extract a range of elements. This works across any dimension.
1D Slicing
import torch
tensor = torch.tensor([10, 20, 30, 40, 50, 60])
print("First 3 elements:", tensor[:3])
print("Last 2 elements:", tensor[-2:])
print("Every other element:", tensor[::2])
print("Elements 1 to 4:", tensor[1:5])Output:
First 3 elements: tensor([10, 20, 30])
Last 2 elements: tensor([50, 60])
Every other element: tensor([10, 30, 50])
Elements 1 to 4: tensor([20, 30, 40, 50])2D Slicing (Rows and Columns)
import torch
matrix = torch.tensor([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
print("Row 1:", matrix[1])
print("Column 2:", matrix[:, 2])
print("Sub-matrix:\n", matrix[:2, 2:])
print("Every other column:\n", matrix[:, ::2])Output:
Row 1: tensor([5, 6, 7, 8])
Column 2: tensor([ 3, 7, 11])
Sub-matrix:
tensor([[3, 4],
[7, 8]])
Every other column:
tensor([[ 1, 3],
[ 5, 7],
[ 9, 11]])Modifying Values
PyTorch tensors are mutable - you can change their values using the assignment operator.
Modifying a Single Element
import torch
tensor = torch.tensor([1, 2, 3, 4, 5])
print("Original:", tensor)
tensor[2] = 99
print("After tensor[2] = 99:", tensor)Output:
Original: tensor([1, 2, 3, 4, 5])
After tensor[2] = 99: tensor([ 1, 2, 99, 4, 5])Modifying a Row
import torch
matrix = torch.tensor([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
print("Original:\n", matrix)
matrix[1] = torch.tensor([40, 50, 60])
print("After modifying row 1:\n", matrix)Output:
Original:
tensor([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
After modifying row 1:
tensor([[ 1, 2, 3],
[40, 50, 60],
[ 7, 8, 9]])Modifying a Column
import torch
matrix = torch.tensor([
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
])
matrix[:, 2] = torch.tensor([30, 60, 90])
print("After modifying column 2:\n", matrix)Output:
After modifying column 2:
tensor([[ 1, 2, 30],
[ 4, 5, 60],
[ 7, 8, 90]])Modifying a Slice
import torch
matrix = torch.tensor([
[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 10, 11, 12]
])
matrix[0, 2:] = torch.tensor([30, 40])
print("After modifying slice:\n", matrix)Output:
After modifying slice:
tensor([[ 1, 2, 30, 40],
[ 5, 6, 7, 8],
[ 9, 10, 11, 12]])Boolean (Conditional) Indexing
You can access and modify elements based on a condition, which creates a boolean mask:
import torch
tensor = torch.tensor([10, -5, 30, -15, 20, -3])
positives = tensor[tensor > 0]
print("Positive values:", positives)
tensor[tensor < 0] = 0
print("After replacing negatives:", tensor)Output:
Positive values: tensor([10, 30, 20])
After replacing negatives: tensor([10, 0, 30, 0, 20, 0])This is extremely useful for data cleaning, masking, and thresholding operations in neural networks.
Advanced (Fancy) Indexing
Use a list or tensor of indices to access specific, non-contiguous elements:
import torch
tensor = torch.tensor([10, 20, 30, 40, 50, 60])
indices = torch.tensor([0, 2, 4])
selected = tensor[indices]
print("Selected elements:", selected)
tensor[indices] = torch.tensor([100, 300, 500])
print("After modification:", tensor)Output:
Selected elements: tensor([10, 30, 50])
After modification: tensor([100, 20, 300, 40, 500, 60])Important: Views vs Copies
Quick Reference
| Operation | Syntax | Example |
|---|---|---|
| Single element | tensor[i] |
tensor[2] |
| 2D element | tensor[row, col] |
matrix[1, 2] |
| Get Python value | .item() |
tensor[0].item() |
| Row slice | tensor[start:end] |
matrix[1:3] |
| Column slice | tensor[:, col] |
matrix[:, 2] |
| Boolean mask | tensor[condition] |
tensor[tensor > 0] |
| Fancy indexing | tensor[indices] |
tensor[[0, 2, 4]] |
| Modify element | tensor[i] = val |
tensor[2] = 99 |
| Modify slice | tensor[s] = vals |
matrix[0, 1:] = ... |
| Independent copy | .clone() |
tensor[1:4].clone() |
Conclusion
Accessing and modifying tensor values in PyTorch follows familiar Python indexing and slicing conventions, making it intuitive for anyone who has worked with lists or NumPy arrays.
- Use single indexing for individual elements,
- Use slicing for ranges,
- Use boolean indexing for conditional access,
- Use fancy indexing for non-contiguous elements.
- Remember that slices create views (shared memory): use
.clone()when you need an independent copy.
Mastering these operations is fundamental to effective data manipulation and model development in PyTorch.