NumPy View vs Copy: Shallow vs Deep Explained
In NumPy, managing how data is stored and manipulated in memory is crucial for both performance and avoiding unintended side effects. The core difference between a shallow view and a deep copy is that a view shares the exact same memory buffer as the original array, whereas a deep copy creates a completely new, independent array with its own allocated memory. Modifying the elements of a view will directly alter the original array, while modifying a deep copy leaves the original array untouched.
What Is a Shallow View?
A view (often referred to as a shallow copy) is a new
ndarray object that references the data of an existing
array. It does not allocate memory for the data itself; instead, it
looks at the original buffer with a potentially different shape, stride,
or offset.
Characteristics of a View
- Shared Memory: Any changes made to the values inside a view immediately reflect in the original array, and vice versa.
- Memory Efficient: Creating a view takes \(O(1)\) time and virtually no extra RAM, making it extremely fast.
- Creation Methods: Basic slicing (e.g.,
b = a[1:4]) or calling the.view()method creates a view.
import numpy as np
original = np.array([1, 2, 3, 4])
view_arr = original[1:3]
view_arr[0] = 99
print(original) # Output: [ 1, 99, 3, 4]What Is a Deep Copy?
A deep copy is a brand-new array containing an identical duplicate of the original data stored in a separate memory location.
Characteristics of a Copy
- Independent Memory: Modifying the copy has no effect on the original array.
- Resource Intensive: Creating a copy requires allocating new memory and copying over every byte (\(O(n)\) time and space).
- Creation Methods: Created using the
.copy()method or triggered implicitly by advanced indexing (such as integer array indexing or boolean masks).
import numpy as np
original = np.array([1, 2, 3, 4])
copy_arr = original.copy()
copy_arr[0] = 99
print(original) # Output: [1, 2, 3, 4]How to Check If an Array Owns Its Data
You can check whether an array is a view or a copy by inspecting its
base attribute:
- If
arr.baseisNone, the array owns its memory (it is an original or a deep copy). - If
arr.basereferences another array, it is a view.
a = np.array([1, 2, 3])
b = a[0:2]
c = a.copy()
print(b.base is a) # True -> b is a view of a
print(c.base is None) # True -> c owns its memoryComparison Summary
| Feature | Shallow View | Deep Copy |
|---|---|---|
| Memory Allocation | Shared with original | Separate block of memory |
| Mutation Effects | Modifying view mutates original | Isolated from original |
| Creation Method | Basic slicing,
arr.view() |
arr.copy(), advanced
indexing |
| Performance | Extremely fast (\(O(1)\)) | Slower (\(O(n)\) memory and time) |
arr.base
Value |
Points to original array | None |
When to Use Each
- Use a View when processing large datasets where memory usage and speed are critical, and when modifications are either intended to update the source data or no modifications will take place.
- Use a Copy when you need to transform, clean, or experiment with a subset of data without risking the integrity of the original dataset.