Skip to main content

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
tip

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

Slicing creates a view, not a copy

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

OperationSyntaxExample
Single elementtensor[i]tensor[2]
2D elementtensor[row, col]matrix[1, 2]
Get Python value.item()tensor[0].item()
Row slicetensor[start:end]matrix[1:3]
Column slicetensor[:, col]matrix[:, 2]
Boolean masktensor[condition]tensor[tensor > 0]
Fancy indexingtensor[indices]tensor[[0, 2, 4]]
Modify elementtensor[i] = valtensor[2] = 99
Modify slicetensor[s] = valsmatrix[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.