{"id":2615,"library":"ndindex","title":"Ndindex","description":"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.","status":"active","version":"1.10.1","language":"python","source_language":"en","source_url":"https://github.com/Quansight-Labs/ndindex","tags":["numpy","indexing","array","slice","utility"],"install":[{"cmd":"pip install ndindex","lang":"bash","label":"Install stable version"}],"dependencies":[{"reason":"Core functionality relies on concepts and types from NumPy for array indexing.","package":"numpy","optional":false}],"imports":[{"note":"The primary API entry point is the `ndindex()` function, usually imported directly to convert Python index objects to ndindex objects. Direct `import ndindex` requires prefixing all calls, which is less common for this library's typical usage.","wrong":"import ndindex","symbol":"ndindex","correct":"from ndindex import ndindex"},{"note":"Classes like `Slice`, `Integer`, `Tuple` are typically imported directly for convenience, or accessed via `ndindex.Slice` if `ndindex` is imported as a module.","wrong":"import ndindex.Slice","symbol":"Slice","correct":"from ndindex import Slice"}],"quickstart":{"code":"import numpy as np\nfrom ndindex import ndindex, Slice, Tuple\n\n# Create an ndindex object from a Python slice\nidx_slice = ndindex(slice(1, 10, 2))\nprint(f\"Ndindex from slice: {idx_slice}\")\n\n# Canonicalize a slice (reduce to simplest form)\ncanonical_slice = Slice(None, 10).reduce()\nprint(f\"Canonical slice: {canonical_slice}\")\n\n# Canonicalize for a specific array shape\nshaped_slice = Slice(-5, 10, 2).reduce(12)\nprint(f\"Slice reduced for shape 12: {shaped_slice}\")\n\n# Manipulate a tuple index\ntuple_idx = Tuple(0, slice(0, 5), None, 1)\nprint(f\"Tuple index: {tuple_idx}\")\n\n# Get the raw Python index to use with NumPy\nnp_array = np.arange(20).reshape(2, 10)\nraw_index = tuple_idx.raw\nprint(f\"Raw Python index: {raw_index}\")\n\n# Use the raw index with a NumPy array\ntry:\n    indexed_array = np.arange(100).reshape(10, 10)[raw_index] # Example with a 2D array\n    print(f\"Indexed array shape: {indexed_array.shape}\")\nexcept IndexError as e:\n    print(f\"Indexing with {raw_index} failed due to: {e}\")","lang":"python","description":"This quickstart demonstrates creating `ndindex` objects from basic Python indices, canonicalizing slices (both generally and for a specific array shape), and converting an `ndindex` object back into a raw Python index suitable for use with NumPy arrays. It highlights the `reduce()` method for canonicalization and `raw` attribute for NumPy compatibility."},"warnings":[{"fix":"Always use `try-except IndexError` blocks when applying `idx.raw` to a NumPy array if out-of-bounds indexing is a possibility. Perform explicit bounds checking if needed before constructing the `ndindex` object if strict validation is required.","message":"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]","severity":"gotcha","affected_versions":"All versions"},{"fix":"To canonicalize an index or reduce it to its simplest equivalent form, you must explicitly call the `.reduce()` method on the `ndindex` object (e.g., `Slice(None, 10).reduce()`). If comparing two indices for equivalence over a specific array shape, use `idx1.reduce(shape) == idx2.reduce(shape)` rather than `idx1 == idx2`. [1, 4]","message":"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]","severity":"gotcha","affected_versions":"All versions"},{"fix":"To check if two `ndindex` objects are equivalent in terms of the elements they would select from an array, first call their `.reduce()` method, optionally with an array `shape` argument if the context is known. Then compare the reduced objects: `idx1.reduce(shape) == idx2.reduce(shape)`. [1]","message":"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]","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"search_vec":"'1.10.1':57 'activ':62 'align':46 'api':39 'array':21,29,70 'cadenc':64 'contain':32 'correct':44 'current':54 'design':7 'ellips':25 'ensur':43 'includ':22 'index':51,69 'indic':18 'integ':24 'integer/boolean':28 'librari':6 'maintain':60 'manipul':11 'ndarray':50 'ndindex':1,2 'none':26 'numpi':20,48,68 'object':12,42 'provid':36 'python':5 'recent':66 'releas':63 'repres':9 'rule':52 'semant':45 'serv':15 'slice':23,71 'tupl':31 'type':34 'uniform':38 'updat':67 'util':72 'valid':17 'version':55","created_at":"2026-04-11T01:35:33.824293+00:00","updated_at":"2026-04-16T17:20:31.294741+00:00","problems":[{"fix":"Access the underlying NumPy-compatible index by using the `.raw` attribute of the `ndindex` object (e.g., `array[idx.raw]`).","cause":"This error occurs when an `ndindex` object is used directly to index a NumPy array without converting it to a 'raw' NumPy-compatible index. The NumPy array expects native index types, not `ndindex` wrapper objects.","error":"IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices"},{"fix":"To access the individual index objects within an `ndindex.Tuple`, use the `.args` attribute (which returns the `ndindex` types) or `.raw` (which returns the raw Python types for indexing, e.g., `idx.raw[0]`).","cause":"An `ndindex.Tuple` object is being treated like a native Python tuple by attempting to access its elements using square brackets (e.g., `idx[0]`). `ndindex` objects do not support direct subscripting in this manner for their internal components.","error":"TypeError: 'Tuple' object is not subscriptable"},{"fix":"To find the indices of specific values in a NumPy array, use `numpy.where()` (e.g., `np.where(array == value)`).","cause":"This error arises when trying to use the built-in Python `list.index()` method on a NumPy `ndarray` object. NumPy arrays do not have an `index` method like Python lists.","error":"AttributeError: 'numpy.ndarray' object has no attribute 'index'"},{"fix":"Explicitly convert the floating-point number to an integer using `int()` before using it as an index or in functions that require integer arguments (e.g., `array[int(float_index)]`).","cause":"This commonly occurs when a floating-point number is provided in a context that strictly expects an integer, such as when using it directly as an array index or as an argument to functions like `range()`.","error":"TypeError: 'float' object cannot be interpreted as an integer"}],"ecosystem":"pypi","meta_description":null,"install_score":null,"quickstart_score":null,"quickstart_tag":null,"pypi_latest":"1.10.1","cli_name":"","cli_version":null,"type":"library","homepage":"https://quansight-labs.github.io/ndindex/","github":null,"docs":null,"changelog":null,"pypi":"https://pypi.org/project/ndindex/","npm":null,"openapi_spec":null,"status_page":null,"smithery":null,"categories":["data","serialization"],"base_url":null,"auth_type":null,"provenance":{"verified_status":"passing","verified_at":"2026-06-28","last_verified":"2026-08-28","next_check":"2026-07-28","install_tag":null}}