Two NumPy array objects can expose different selections while referring to overlapping bytes in the same data buffer. That distinction determines whether an in-place write through a derived array also changes its source.
Use np.shares_memory(source, candidate) for a pair-specific overlap check. The .base attribute shows whether an array is backed by another object, but a chained view may have a different base object than the source being compared.
Basic slicing creates a view, while advanced indexing and .copy() create independent arrays. Exact overlap checks can be expensive for pathological stride layouts; a finite max_work limit or np.may_share_memory() provides the documented bounded or conservative alternative.
Related: Index and slice arrays
Related: Memory-map an array
import numpy as np source = np.arange(6) basic_slice = source[1:4] advanced_index = source[[1, 2, 3]] explicit_copy = source[1:4].copy()
candidates = { "basic_slice": basic_slice, "advanced_index": advanced_index, "explicit_copy": explicit_copy, } for name, candidate in candidates.items(): print( f"{name}: shares_memory={np.shares_memory(source, candidate)}, " f"base_is_none={candidate.base is None}" )
basic_slice[0] = 99 advanced_index[1] = 77 explicit_copy[2] = 55 print("source after edits:", source) print("basic_slice after edit:", basic_slice) print("advanced_index after edit:", advanced_index) print("explicit_copy after edit:", explicit_copy)
import numpy as np source = np.arange(6) basic_slice = source[1:4] advanced_index = source[[1, 2, 3]] explicit_copy = source[1:4].copy() candidates = { "basic_slice": basic_slice, "advanced_index": advanced_index, "explicit_copy": explicit_copy, } for name, candidate in candidates.items(): print( f"{name}: shares_memory={np.shares_memory(source, candidate)}, " f"base_is_none={candidate.base is None}" ) basic_slice[0] = 99 advanced_index[1] = 77 explicit_copy[2] = 55 print("source after edits:", source) print("basic_slice after edit:", basic_slice) print("advanced_index after edit:", advanced_index) print("explicit_copy after edit:", explicit_copy)
$ python3 array-check-view-copy.py basic_slice: shares_memory=True, base_is_none=False advanced_index: shares_memory=False, base_is_none=True explicit_copy: shares_memory=False, base_is_none=True source after edits: [ 0 99 2 3 4 5] basic_slice after edit: [99 2 3] advanced_index after edit: [ 1 77 3] explicit_copy after edit: [ 1 2 55]
The basic slice reports True and propagates 99 into source. Both copies report False, and their 77 and 55 edits remain isolated. The .base values agree for these direct examples, but np.shares_memory() is the pair-specific check.