Ndindex
ndindex is a Python library designed for representing and manipulating objects that can serve as valid indices for NumPy arrays, including slices, integers, ellipses, None, and integer/boolean arrays, and tuples containing these types. It provides a uniform API for these objects, ensuring correct semantics aligned with NumPy's `ndarray` indexing rules. The current version is 1.10.1, and it maintains an active release cadence with recent updates.
Warnings
- gotcha ndindex objects assume that indexing will not raise an `IndexError`. Operations like `reduce()` and transformations do not validate against array bounds; they assume the index is valid for *some* array. Users must handle `IndexError` when applying `ndindex.raw` to an actual NumPy array. [1, 4, 6, 8]
- gotcha By default, `ndindex` class constructors (e.g., `Slice(None, 10)`) only perform basic type checking and do not canonicalize the index. This means `Slice(None, 10)` is not strictly equal to `Slice(0, 10, 1)` by default. [1, 4, 8]
- gotcha Direct `==` comparison between `ndindex` objects performs exact equality checking, which might not reflect if two indices actually refer to the same elements in an array. For instance, `Slice(0, 10)` and `Slice(None, 10)` are not equal with `==`. [1]
Install
-
pip install ndindex
Imports
- ndindex
from ndindex import ndindex
- Slice
from ndindex import Slice
Quickstart
import numpy as np
from ndindex import ndindex, Slice, Tuple
# Create an ndindex object from a Python slice
idx_slice = ndindex(slice(1, 10, 2))
print(f"Ndindex from slice: {idx_slice}")
# Canonicalize a slice (reduce to simplest form)
canonical_slice = Slice(None, 10).reduce()
print(f"Canonical slice: {canonical_slice}")
# Canonicalize for a specific array shape
shaped_slice = Slice(-5, 10, 2).reduce(12)
print(f"Slice reduced for shape 12: {shaped_slice}")
# Manipulate a tuple index
tuple_idx = Tuple(0, slice(0, 5), None, 1)
print(f"Tuple index: {tuple_idx}")
# Get the raw Python index to use with NumPy
np_array = np.arange(20).reshape(2, 10)
raw_index = tuple_idx.raw
print(f"Raw Python index: {raw_index}")
# Use the raw index with a NumPy array
try:
indexed_array = np.arange(100).reshape(10, 10)[raw_index] # Example with a 2D array
print(f"Indexed array shape: {indexed_array.shape}")
except IndexError as e:
print(f"Indexing with {raw_index} failed due to: {e}")