The PyTorch tensor and Numpy array handle numerical data similarly but belong to different libraries. PyTorch is for deep learning, and Numpy is for numerical computing.
The easiest way to convert Pytorch tensor to a numpy array is using the .numpy() method for tensors provided by PyTorch. For example, if I have a tensor like tensor = torch.tensor([1, 2, 3]), then `tensor.numpy()` will give me the NumPy array.
Basic Conversion: CPU Tensor (No Gradients)
The basic conversion is CPU-based without gradients, and no GPU is involved. The resulting NumPy array shares memory with the tensor (modifying one affects the other).
import torch tensor = torch.tensor([1, 2, 3]) print(tensor) # Output: tensor([1, 2, 3], device='cuda:0') print(tensor.dtype) # Output: torch.int64 numpy_array = tensor.numpy() # Shares memory with tensor print(numpy_array) # Output: [1 2 3] print(type(numpy_array)) # Output: <class 'numpy.ndarray'>
Handling GPU Tensors
If you are working with GPUs, you must first move GPU tensors to the CPU. This is necessary before converting a GPU tensor to a NumPy array, or you will get an error.
The conversion creates a copy (no memory sharing).
import torch gpu_tensor = torch.tensor([1, 2, 3], device="cuda") print(gpu_tensor) # Output: tensor([1, 2, 3]) # Move to CPU cpu_tensor = gpu_tensor.cpu() print(cpu_tensor.dtype) # Output: torch.int64 numpy_array = cpu_tensor.numpy() # Shares memory with tensor print(numpy_array) # Output: [1 2 3] print(type(numpy_array)) # Output: <class 'numpy.ndarray'>
Tensors with Gradients (Autograd)
If you have a Tensor with requires_grad=True, your first step would be to detach from the computation graph using the .detach() method. Then, convert it into a numpy array.
import torch grad_tensor = torch.tensor([1.0, 2.0], requires_grad=True) print(grad_tensor) # Output: tensor([1., 2.], requires_grad=True) print(type(grad_tensor)) # Output: <class 'torch.Tensor'> # Convert tensor to numpy array numpy_array = grad_tensor.detach().numpy() print(numpy_array) # Output: [1. 2.] print(type(numpy_array)) # Output: <class 'numpy.ndarray'>
Ensuring a Copy (No Memory Sharing)
If you want to create a numpy array out of tensor and avoid memory sharing, explicitly create a copy.
First, initialize a tensor, then create a copy using the .clone() method, and then convert that clone into a numpy array using the .numpy() method.
import torch tensor = torch.tensor([1.0, 2.0]) print(tensor) # Output: tensor([1., 2.]) print(type(tensor)) # Output: <class 'torch.Tensor'> # Clone the tensor first and then convert it to a numpy array numpy_copy = tensor.clone().numpy() print(numpy_copy) # Output: [1. 2.] print(type(numpy_copy)) # Output: <class 'numpy.ndarray'>
Data Type Considerations
Since PyTorch and NumPy have compatible data types, many can be directly mapped (e.g., torch.float32 → numpy.float32). However, explicit conversion may sometimes be required to ensure consistency and avoid unintended type mismatches.
import torch import numpy as np tensor = torch.tensor([1.5, 2.5], dtype=torch.float64) print(tensor) # Output: tensor([1.5000, 2.5000], dtype=torch.float64) print(type(tensor)) # Output: <class 'torch.Tensor'> # Convert it to a NumPy array and cast it to float32 numpy_array = tensor.numpy().astype(np.float32) print(numpy_array) # Output: [1.5 2.5] print(type(numpy_array)) # Output: <class 'numpy.ndarray'>
Non-Contiguous Tensors
If your input tensors are non-contiguous, use the .contiguous() method to make it contiguous. After that, you can apply .numpy() method.
import torch non_contiguous = torch.tensor([[1, 2], [3, 4]]).t() print(non_contiguous) # Output: tensor([[1, 3], # [2, 4]]) print(type(non_contiguous)) # Output: <class 'torch.Tensor'> # Make it contiguous contiguous_tensor = non_contiguous.contiguous() # Convert it to a NumPy array numpy_array = contiguous_tensor.numpy() print(numpy_array) # Output: [[1 3] # [2 4]] print(type(numpy_array)) # Output: <class 'numpy.ndarray'>
Sparse Tensors
If you are dealing with a sparse tensor, convert to dense format using the .to_dense() method and then chain the .numpy() method.
import torch sparse_tensor = torch.sparse_coo_tensor( indices=[[0, 1], [1, 2]], values=[3, 4], size=(2, 3)) print(sparse_tensor) # Output: tensor(indices=tensor([[0, 1], # [1, 2]]), # values=tensor([3, 4]), # size=(2, 3), nnz=2, layout=torch.sparse_coo) print(type(sparse_tensor)) # Output: <class 'torch.Tensor'> # Make it dense dense_tensor = sparse_tensor.to_dense() # Convert it to a NumPy array numpy_array = dense_tensor.numpy() print(numpy_array) # Output: [[0 3 0] # [0 0 4]] print(type(numpy_array)) # Output: <class 'numpy.ndarray'>
Minimize GPU-to-CPU transfers as much as possible because they are slow for large tensors. If possible, process data directly on the GPU.
If you are working with Scalar Tensors, use the .item() function for Python scalars instead of NumPy.