Easy Tutorial
❮ Numpy Advanced Indexing Home ❯

NumPy Copies and Views

A copy is a complete duplicate of the data. If we modify the copy, it does not affect the original data, and the physical memory locations are different.

A view is an alias or reference to the data, allowing access and manipulation of the original data without creating a copy. If we modify the view, it affects the original data, and the physical memory locations are the same.

Views typically occur when:

Copies typically occur when:

No Copy

Simple assignment does not create a copy of the array object. Instead, it uses the same id() to access the original array. The id() returns a universal identifier for a Python object, similar to a pointer in C.

Additionally, any changes to one array are reflected in the other. For example, changing the shape of one array also changes the shape of the other.

Example

import numpy as np

a = np.arange(6)
print('Our array is:')
print(a)
print('Calling id() function:')
print(id(a))
print('Assigning a to b:')
b = a
print(b)
print('b has the same id():')
print(id(b))
print('Modifying the shape of b:')
b.shape = 3, 2
print(b)
print('The shape of a is also modified:')
print(a)

Output:

Our array is:
[0 1 2 3 4 5]
Calling id() function:
4349302224
Assigning a to b:
[0 1 2 3 4 5]
b has the same id():
4349302224
Modifying the shape of b:
[[0 1]
 [2 3]
 [4 5]]
The shape of a is also modified:
[[0 1]
 [2 3]
 [4 5]]

View or Shallow Copy

The ndarray.view() method creates a new array object, and changes to the dimensions of the new array do not affect the dimensions of the original data.

Example

import numpy as np

# Initially, a is a 3x2 array
a = np.arange(6).reshape(3, 2)
print('Array a:')
print(a)
print('Creating a view of a:')
b = a.view()
print(b)
print('The two arrays have different id():')
print('id() of a:')
print(id(a))
print('id() of b:')
print(id(b))
# Modifying the shape of b does not modify a
b.shape = 2, 3
print('Shape of b:')
print(b)
print('Shape of a:')
print(a)

Output:

Array a:
[[0 1]
 [2 3]
 [4 5]]
Creating a view of a:
[[0 1]
 [2 3]
 [4 5]]
The two arrays have different id():
id() of a:
4314786992
id() of b:
4315171296
Shape of b:
[[0 1 2]
 [3 4 5]]
Shape of a:
[[0 1]
 [2 3]
 [4 5]]

Using slicing to create a view and modifying the data affects the original array:

Example

import numpy as np

arr = np.arange(12)
print('Our array:')
print(arr)
print('Creating a slice:')
a = arr[3:]
b = arr[3:]
a[1] = 123
b[2] = 234
print(arr)
print(id(a), id(b), id(arr[3:]))

Output:

Our array:
[ 0  1  2  3  4  5  6  7  8  9 10 11]
Creating a slice:
[  0   1   2   3 123 234   6   7   8   9  10  11]
4545878416 4545878496 4545878576

Variables a and b are views of a part of arr, and modifications to the views directly reflect in the original data. However, observing the id of a and b, they are different, indicating that while views point to the original data, they are distinct from assignment references.

Copy or Deep Copy

The ndarray.copy() function creates a copy. Modifications to the copy do not affect the original data, and their physical memory locations are different.

Example

import numpy as np

a = np.array([[10, 10], [2, 3], [4, 5]])
print('Array a:')
print(a)
print('Creating a deep copy of a:')
b = a.copy()
print('Array b:')
print(b)

Output:

Array a:
[[10 10]
 [ 2  3]
 [ 4  5]]
Creating a deep copy of a:
Array b:
[[10 10]
 [ 2  3]
 [ 4  5]]
print(b)
# b does not share anything with a
print('Can we write to b to write to a?')
print(b is a)
print('Modify the contents of b:')
b[0,0] = 100
print('Array b after modification:')
print(b)
print('a remains unchanged:')
print(a)

Output result:

Array a:
[[10 10]
 [ 2  3]
 [ 4  5]]
Create a deep copy of a:
Array b:
[[10 10]
 [ 2  3]
 [ 4  5]]
Can we write to b to write to a?
False
Modify the contents of b:
Array b after modification:
[[100  10]
 [  2   3]
 [  4   5]]
a remains unchanged:
[[10 10]
 [ 2  3]
 [ 4  5]]

More related articles

Python Direct Assignment, Shallow Copy, and Deep Copy Explained

❮ Numpy Advanced Indexing Home ❯