Python PyTorch: How to Access and Modify Values of a Tensor in PyTorch
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])
# Access individual elements
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}")
# Extract as Python number
value = tensor[1].item()
print(f"Type: {type(value)}, Value: {value}")
Output:
Type: <class 'torch.Tensor'>, Value: 20
Type: <class 'int'>, Value: 20
Always use .item() when you need a plain Python int or float - for example, when logging metrics, using values in conditionals, or passing to non-PyTorch functions.
2D 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]
])
# Access element at row 1, column 2
print("matrix[1, 2]:", matrix[1, 2].item())
# Same as:
print("matrix[1][2]:", matrix[1][2].item())
Output:
matrix[1, 2]: 6
matrix[1][2]: 6
Accessing 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]
])
# Entire second row
print("Row 1:", matrix[1])
# Entire third column
print("Column 2:", matrix[:, 2])
# Sub-matrix: first 2 rows, last 2 columns
print("Sub-matrix:\n", matrix[:2, 2:])
# All rows, every other column
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)
# Replace the entire second row
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]
])
# Replace the entire third column
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]
])
# Modify first row, last two columns
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])
# Access elements greater than 0
positives = tensor[tensor > 0]
print("Positive values:", positives)
# Replace negative values with 0
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])
# Access elements at indices 0, 2, and 4
indices = torch.tensor([0, 2, 4])
selected = tensor[indices]
print("Selected elements:", selected)
# Modify elements at specific indices
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
When you slice a tensor, the result shares memory with the original tensor. Modifying the slice also modifies the original:
import torch
original = torch.tensor([1, 2, 3, 4, 5])
sliced = original[1:4]
sliced[0] = 99
print("Original:", original) # Also changed!
print("Sliced:", sliced)
Output:
Original: tensor([ 1, 99, 3, 4, 5])
Sliced: tensor([99, 3, 4])
If you need an independent copy, use .clone():
sliced = original[1:4].clone()
sliced[0] = 99
print("Original:", original) # NOT changed
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.