Index Types¶
The ndindex API consists of classes to represent the different kinds of NumPy
indices, Integer, Slice, ellipsis,
Newaxis, Tuple, IntegerArray, and
BooleanArray. Typical usage of ndindex consists of constructing one
of these classes, typically with the ndindex() constructor, then using
the methods on the objects. With a few exceptions, all index classes have the
same set of methods, so that they can be used uniformly regardless of the
actual index type. Consequently, many of the method docstrings below are
duplicated across all the classes. For classes where there is are particular
things of note for a given method, the docstring will be different (for
example, Slice.reduce() notes the specific invariants that the
reduce() method applies to Slice objects). Such
methods will be noted by their “See Also” sections.
- class ndindex.Integer(idx)[source]¶
Represents an integer index on an axis of an nd-array.
Any object that implements
__index__can be used as an integer index.>>> from ndindex import Integer >>> idx = Integer(1) >>> [0, 1, 2][idx.raw] 1 >>> idx = Integer(-3) >>> [0, 1, 2][idx.raw] 0
Note that
Integeritself implements__index__, so it can be used as an index directly. However, it is still recommended to userawfor consistency, as this only works forInteger.See Integer Indices for a description of the semantics of integers as indices.
Note
Integerdoes not represent an integer, but rather an integer index. It does not have most methods thatinthas, and should not be used in non-indexing contexts. See the document on Type Confusion for more details.- __len__()[source]¶
Returns the number of elements indexed by
selfSince
selfis an integer index, this always returns 1. Note that integer indices always remove an axis.
- as_subindex(index)[source]¶
i.as_subindex(j)produces an indexksuch thata[j][k]gives all of the elements ofa[j]that are also ina[i].If
a[j]is a subset ofa[i], thena[j][k] == a[i]. Otherwise,a[j][k] == a[i & j], wherei & jis the intersection ofiandj, that is, the elements ofathat are indexed by bothiandj.For example, in the below diagram,
iandjindex a subset of the arraya.k = i.as_subindex(j)is an index ona[j]that gives the subset ofa[j]also included ina[i]:+------------ self ------------+ | | ------------------- a ----------------------- | | +------------- index -------------+ | | +- self.as_subindex(index) -+
i.as_subindex(j)is currently only implemented whenjis a slice with positive steps and nonnegative start and stop, or a Tuple of the same. To use it with slices with negative start or stop, callreduce()with a shape first.as_subindexcan be seen as the left-inverse of composition, that is, ifa[i] = a[j][k], thenk = i.as_subindex(j), so thatk "=" (j^-1)[i](this only works as a true inverse ifjis a subset ofi).Note that due to symmetry,
a[j][i.as_subindex(j)]anda[i][j.as_subindex(i)]will give the same subarrays ofa, which will be the array of elements indexed by botha[i]anda[j].i.as_subindex(j)may raiseValueErrorin the case that the indicesiandjdo not intersect at all.Examples
An example usage of
as_subindexis to split an index up into subindices of chunks of an array. For example, say a 1-D arrayais chunked up into chunks of sizeN, so thata[0:N],a[N:2*N],[2*N:3*N], etc. are stored separately. Then an indexa[i]can be reindexed onto the chunks viai.as_subindex(Slice(0, N)),i.as_subindex(Slice(N, 2*N)), etc.>>> from ndindex import Slice >>> i = Slice(5, 15) >>> j1 = Slice(0, 10) >>> j2 = Slice(10, 20) >>> a = list(range(20)) >>> a[i.raw] [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> a[j1.raw] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[j2.raw] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> k1 = i.as_subindex(j1) >>> k1 Slice(5, 10, 1) >>> k2 = i.as_subindex(j2) >>> k2 Slice(0, 5, 1) >>> a[j1.raw][k1.raw] [5, 6, 7, 8, 9] >>> a[j2.raw][k2.raw] [10, 11, 12, 13, 14]
See also
ndindex.ChunkSize.as_subchunksa high-level iterator that efficiently gives only those chunks that intersect with a given index
- isempty(shape=None)[source]¶
Returns whether self always indexes an empty array
An empty array is an array whose shape contains at least one 0. Note that scalars (arrays with shape
()) are not considered empty.shapecan beNone(the default), or an array shape. If it isNone, isempty() will returnTruewhenselfis always empty for any array shape. However, if it givesFalse, it could still give an empty array for some array shapes, but not all. If you know the shape of the array that will be indexed, useidx.isempty(shape)and the result will be correct for arrays of shapeshape. Ifshapeis given andselfwould raise anIndexErroron an array of shapeshape,isempty()also raisesIndexError.>>> from ndindex import Tuple, Slice >>> Tuple(0, slice(0, 1)).isempty() False >>> Tuple(0, slice(0, 0)).isempty() True >>> Slice(5, 10).isempty() False >>> Slice(5, 10).isempty(4) True
See also
- isvalid(shape, _axis=0)[source]¶
Check whether a given index is valid on an array of a given shape.
Returns
Trueif an array of shapeshapecan be indexed byselfandFalseif it would raiseIndexError.>>> from ndindex import ndindex >>> ndindex(3).isvalid((4,)) True >>> ndindex(3).isvalid((2,)) False
Note that some indices can never be valid and will raise a
IndexErrororTypeErrorif you attempt to construct them.>>> ndindex((..., 0, ...)) Traceback (most recent call last): ... IndexError: an index can only have a single ellipsis ('...') >>> ndindex(slice(True)) Traceback (most recent call last): ... TypeError: 'bool' object cannot be interpreted as an integer
See also
- newshape(shape)[source]¶
Returns the shape of
a[idx.raw], assumingahas shapeshape.shapeshould be a tuple of ints, or an int, which is equivalent to a 1-D shape.Raises
IndexErrorifselfwould be invalid for an array of shapeshape.>>> from ndindex import Slice, Integer, Tuple >>> shape = (6, 7, 8) >>> Integer(1).newshape(shape) (7, 8) >>> Integer(10).newshape(shape) Traceback (most recent call last): ... IndexError: index 10 is out of bounds for axis 0 with size 6 >>> Slice(2, 5).newshape(shape) (3, 7, 8) >>> Tuple(0, ..., Slice(1, 3)).newshape(shape) (7, 2)
See also
- property raw¶
Return the equivalent of
selfthat can be used as an indexNumPy does not allow custom objects to be used as indices, with the exception of integer indices, so to use an ndindex object as an index, it is necessary to use
raw.>>> from ndindex import Slice >>> import numpy as np >>> a = np.arange(5) >>> s = Slice(2, 4) >>> a[s] Traceback (most recent call last): ... IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices >>> a[s.raw] array([2, 3])
- reduce(shape=None, *, axis=0, negative_int=False, axiserror=False)[source]¶
Reduce an Integer index on an array of shape
shape.The result will either be
IndexErrorif the index is invalid for the given shape, or an Integer index where the value is nonnegative.If
negative_intisTrueand ashapeis provided, then the result will be an Integer index where the value is negative.>>> from ndindex import Integer >>> idx = Integer(-5) >>> idx.reduce((3,)) Traceback (most recent call last): ... IndexError: index -5 is out of bounds for axis 0 with size 3 >>> idx.reduce((9,)) Integer(4)
- selected_indices(shape, axis=None)[source]¶
Return an iterator over all indices that are selected by
selfon an array of shapeshape.The result is a set of indices
isuch that[a[i] for i in idx.selected_indices(a.shape)]is all the elements ofa[idx]. The indices are all iterated over in C (i.e., row major) order.>>> from ndindex import Slice, Tuple >>> idx = Slice(5, 10) >>> list(idx.selected_indices(20)) [Integer(5), Integer(6), Integer(7), Integer(8), Integer(9)] >>> idx = Tuple(Slice(5, 10), Slice(0, 2)) >>> list(idx.selected_indices((20, 3))) [Tuple(5, 0), Tuple(5, 1), Tuple(6, 0), Tuple(6, 1), Tuple(7, 0), Tuple(7, 1), Tuple(8, 0), Tuple(8, 1), Tuple(9, 0), Tuple(9, 1)]
To correspond these indices to the elements of
a[idx], you can useiter_indices(idx.newshape(shape)), since both iterators iterate the indices in C order.>>> from ndindex import iter_indices >>> idx = Tuple(Slice(3, 5), Slice(0, 2)) >>> shape = (5, 5) >>> import numpy as np >>> a = np.arange(25).reshape(shape) >>> for a_idx, (new_idx,) in zip( ... idx.selected_indices(shape), ... iter_indices(idx.newshape(shape))): ... print(a_idx, new_idx, a[a_idx.raw], a[idx.raw][new_idx.raw]) Tuple(3, 0) Tuple(0, 0) 15 15 Tuple(3, 1) Tuple(0, 1) 16 16 Tuple(4, 0) Tuple(1, 0) 20 20 Tuple(4, 1) Tuple(1, 1) 21 21
See also
ndindex.iter_indicesAn iterator of indices to select every element for arrays of a given shape.
ndindex.ChunkSize.as_subchunksA high-level iterator that efficiently gives only those chunks that intersect with a given index
- class ndindex.Slice[source]¶
Represents a slice on an axis of an nd-array.
Slice(x)with one argument is equivalent toSlice(None, x).Slice(x, y)with two arguments is equivalent toSlice(x, y, None).startandstopcan be any integer, orNone.stepcan be any nonzero integer orNone.Slice(a, b)is the same as the syntaxa:bin an index andSlice(a, b, c)is the same asa:b:c. An argument beingNoneis equivalent to the syntax where the item is omitted, for example,Slice(None, None, k)is the same as the syntax::k.Slice.argsalways has three arguments, and does not make any distinction between, for instance,Slice(x, y)andSlice(x, y, None). This is because Python itself does not make the distinction betweenx:yandx:y:syntactically.See Slices for a complete description of the semantics of slices.
Slice has attributes
start,stop, andstepto access the corresponding attributes.>>> from ndindex import Slice >>> s = Slice(10) >>> s Slice(None, 10, None) >>> print(s.start) None >>> s.args (None, 10, None) >>> s.raw slice(None, 10, None)
For most use cases, it’s more convenient to create Slice objects using
ndindex[slice], which allows usinga:bslicing syntax:>>> from ndindex import ndindex >>> ndindex[0:10] Slice(0, 10, None)
- __len__()[source]¶
len()gives the maximum size of an axis sliced withself.An actual array may produce a smaller size if it is smaller than the bounds of the slice. For instance,
[0, 1, 2][2:4]only has 1 element but the maximum length of the slice2:4is 2.>>> from ndindex import Slice >>> [0, 1, 2][2:4] [2] >>> len(Slice(2, 4)) 2 >>> [0, 1, 2, 3][2:4] [2, 3]
If there is no such maximum, it raises
ValueError.>>> # From the second element to the end, which could have any size >>> len(Slice(1, None)) Traceback (most recent call last): ... ValueError: Cannot determine max length of slice
The
Slice.reduce()method with ashapeargument returns aSlicethat always has a correctlenwhich doesn’t raiseValueError.>>> Slice(2, 4).reduce(3) Slice(2, 3, 1) >>> len(_) 1
Be aware that
len(Slice)only gives the size of the axis being sliced. It does not say anything about the total shape of the array. In particular, the array may be empty after slicing if one of its dimensions is 0, but the other dimensions may be nonzero. To check if an array will empty after indexing, useisempty().See also
- as_subindex(index)[source]¶
i.as_subindex(j)produces an indexksuch thata[j][k]gives all of the elements ofa[j]that are also ina[i].If
a[j]is a subset ofa[i], thena[j][k] == a[i]. Otherwise,a[j][k] == a[i & j], wherei & jis the intersection ofiandj, that is, the elements ofathat are indexed by bothiandj.For example, in the below diagram,
iandjindex a subset of the arraya.k = i.as_subindex(j)is an index ona[j]that gives the subset ofa[j]also included ina[i]:+------------ self ------------+ | | ------------------- a ----------------------- | | +------------- index -------------+ | | +- self.as_subindex(index) -+
i.as_subindex(j)is currently only implemented whenjis a slice with positive steps and nonnegative start and stop, or a Tuple of the same. To use it with slices with negative start or stop, callreduce()with a shape first.as_subindexcan be seen as the left-inverse of composition, that is, ifa[i] = a[j][k], thenk = i.as_subindex(j), so thatk "=" (j^-1)[i](this only works as a true inverse ifjis a subset ofi).Note that due to symmetry,
a[j][i.as_subindex(j)]anda[i][j.as_subindex(i)]will give the same subarrays ofa, which will be the array of elements indexed by botha[i]anda[j].i.as_subindex(j)may raiseValueErrorin the case that the indicesiandjdo not intersect at all.Examples
An example usage of
as_subindexis to split an index up into subindices of chunks of an array. For example, say a 1-D arrayais chunked up into chunks of sizeN, so thata[0:N],a[N:2*N],[2*N:3*N], etc. are stored separately. Then an indexa[i]can be reindexed onto the chunks viai.as_subindex(Slice(0, N)),i.as_subindex(Slice(N, 2*N)), etc.>>> from ndindex import Slice >>> i = Slice(5, 15) >>> j1 = Slice(0, 10) >>> j2 = Slice(10, 20) >>> a = list(range(20)) >>> a[i.raw] [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> a[j1.raw] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[j2.raw] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> k1 = i.as_subindex(j1) >>> k1 Slice(5, 10, 1) >>> k2 = i.as_subindex(j2) >>> k2 Slice(0, 5, 1) >>> a[j1.raw][k1.raw] [5, 6, 7, 8, 9] >>> a[j2.raw][k2.raw] [10, 11, 12, 13, 14]
See also
ndindex.ChunkSize.as_subchunksa high-level iterator that efficiently gives only those chunks that intersect with a given index
- isempty(shape=None)[source]¶
Returns whether self always indexes an empty array
An empty array is an array whose shape contains at least one 0. Note that scalars (arrays with shape
()) are not considered empty.shapecan beNone(the default), or an array shape. If it isNone, isempty() will returnTruewhenselfis always empty for any array shape. However, if it givesFalse, it could still give an empty array for some array shapes, but not all. If you know the shape of the array that will be indexed, useidx.isempty(shape)and the result will be correct for arrays of shapeshape. Ifshapeis given andselfwould raise anIndexErroron an array of shapeshape,isempty()also raisesIndexError.>>> from ndindex import Tuple, Slice >>> Tuple(0, slice(0, 1)).isempty() False >>> Tuple(0, slice(0, 0)).isempty() True >>> Slice(5, 10).isempty() False >>> Slice(5, 10).isempty(4) True
See also
- isvalid(shape)[source]¶
Check whether a given index is valid on an array of a given shape.
Returns
Trueif an array of shapeshapecan be indexed byselfandFalseif it would raiseIndexError.>>> from ndindex import ndindex >>> ndindex(3).isvalid((4,)) True >>> ndindex(3).isvalid((2,)) False
Note that some indices can never be valid and will raise a
IndexErrororTypeErrorif you attempt to construct them.>>> ndindex((..., 0, ...)) Traceback (most recent call last): ... IndexError: an index can only have a single ellipsis ('...') >>> ndindex(slice(True)) Traceback (most recent call last): ... TypeError: 'bool' object cannot be interpreted as an integer
See also
- newshape(shape)[source]¶
Returns the shape of
a[idx.raw], assumingahas shapeshape.shapeshould be a tuple of ints, or an int, which is equivalent to a 1-D shape.Raises
IndexErrorifselfwould be invalid for an array of shapeshape.>>> from ndindex import Slice, Integer, Tuple >>> shape = (6, 7, 8) >>> Integer(1).newshape(shape) (7, 8) >>> Integer(10).newshape(shape) Traceback (most recent call last): ... IndexError: index 10 is out of bounds for axis 0 with size 6 >>> Slice(2, 5).newshape(shape) (3, 7, 8) >>> Tuple(0, ..., Slice(1, 3)).newshape(shape) (7, 2)
See also
- reduce(shape=None, *, axis=0, negative_int=False)[source]¶
Slice.reducereturns a slice that is canonicalized for an array of the given shape, or for any shape ifshapeisNone(the default).Slice.reduceis a perfect canonicalization, meaning that two slices are equal—for all array shapes ifshape=Noneor for arrays of shapeshapeotherwise—if and only if theyreduceto the sameSliceobject. Note that ndindex objects do not simplify automatically, and==only does exact equality comparison, so to test that two slices are equal, useslice1.reduce(shape) == slice2.reduce(shape).If
shapeisNone, the following properties hold after callingreduce():startis notNone.stopis notNone, when possible. The reducedstopcan only beNoneif the originalstopis.stepis notNone.stepis as close to 0 as possible.If the slice is always empty, the resulting slice will be
Slice(0, 0, 1). However, one should prefer theisemptymethod to test if a slice is always empty.
In particular,
stopmay beNone, even after canonicalization withreduce()with noshape. This is because some slices are impossible to represent withoutNonewithout making assumptions about the array shape. For example,Slice(0, None)cannot be equivalent to a slice withstop != Nonefor all array shapes. To get a slice where thestart,stop, andstepare always integers, usereduce(shape)with an explicit array shape.Note that
Sliceobjects that index a single element are not canonicalized toInteger, because integer indices always remove an axis whereas slices keep the axis. Furthermore, slices cannot raiseIndexErrorexcept on arrays with shape equal to().>>> from ndindex import Slice >>> Slice(10).reduce() Slice(0, 10, 1) >>> Slice(1, 3, 3).reduce() Slice(1, 2, 1)
If an explicit shape is given, the following properties are true after calling
Slice.reduce(shape):start,stop, andstepare notNone,startis nonnegative.stopis nonnegative whenever possible. In particular,stopis only negative when it has to be to represent the given slice, i.e., a slice with negativestepthat indexes more than 1 element and indexes the first (index0) element (in this case, it will be-n - 1wherenis the size of the axis being sliced).stopis as small as possible for positivestepor large as possible for negativestep.stepis as close to 0 as possible.If the slice is empty for the given shape, the resulting slice will be
Slice(0, 0, 1). However, one should prefer theisemptymethod to test if a slice is always empty.If the slice indexes a single element, the resulting slice will be of the form
Slice(i, i+1, 1). However, one should prefer usinglen(s.reduce(shape)) == 1to test if a slice indexes exactly 1 element.len()gives the true size of the axis for a sliced array of the given shape, and never raisesValueError.
The
axisargument can be used to specify an axis of the shape (by default,axis=0). For convenience,shapecan be passed as an integer for a single dimension.>>> from ndindex import Slice >>> Slice(1, 10).reduce(3) Slice(1, 3, 1) >>> Slice(-1, 1, -2).reduce(4) Slice(3, 4, 1) >>> Slice(1, 10, 3).reduce((4, 5), axis=0) Slice(1, 2, 1) >>> Slice(1, 10, 3).reduce((4, 5), axis=1) Slice(1, 5, 3)
>>> s = Slice(2, None) >>> len(s) Traceback (most recent call last): ... ValueError: Cannot determine max length of slice >>> s.reduce((5,)) Slice(2, 5, 1) >>> len(_) 3
- selected_indices(shape, axis=None)[source]¶
Return an iterator over all indices that are selected by
selfon an array of shapeshape.The result is a set of indices
isuch that[a[i] for i in idx.selected_indices(a.shape)]is all the elements ofa[idx]. The indices are all iterated over in C (i.e., row major) order.>>> from ndindex import Slice, Tuple >>> idx = Slice(5, 10) >>> list(idx.selected_indices(20)) [Integer(5), Integer(6), Integer(7), Integer(8), Integer(9)] >>> idx = Tuple(Slice(5, 10), Slice(0, 2)) >>> list(idx.selected_indices((20, 3))) [Tuple(5, 0), Tuple(5, 1), Tuple(6, 0), Tuple(6, 1), Tuple(7, 0), Tuple(7, 1), Tuple(8, 0), Tuple(8, 1), Tuple(9, 0), Tuple(9, 1)]
To correspond these indices to the elements of
a[idx], you can useiter_indices(idx.newshape(shape)), since both iterators iterate the indices in C order.>>> from ndindex import iter_indices >>> idx = Tuple(Slice(3, 5), Slice(0, 2)) >>> shape = (5, 5) >>> import numpy as np >>> a = np.arange(25).reshape(shape) >>> for a_idx, (new_idx,) in zip( ... idx.selected_indices(shape), ... iter_indices(idx.newshape(shape))): ... print(a_idx, new_idx, a[a_idx.raw], a[idx.raw][new_idx.raw]) Tuple(3, 0) Tuple(0, 0) 15 15 Tuple(3, 1) Tuple(0, 1) 16 16 Tuple(4, 0) Tuple(1, 0) 20 20 Tuple(4, 1) Tuple(1, 1) 21 21
See also
ndindex.iter_indicesAn iterator of indices to select every element for arrays of a given shape.
ndindex.ChunkSize.as_subchunksA high-level iterator that efficiently gives only those chunks that intersect with a given index
- class ndindex.ellipsis[source]¶
Represents an ellipsis index, i.e.,
...(orEllipsis).Ellipsis indices by themselves return the full array. Inside of a tuple index, an ellipsis skips 0 or more axes of the array so that everything after the ellipsis indexes the last axes of the array. A tuple index can have at most one ellipsis.
See Ellipses for more details on the semantics of ellipsis indices.
For example
a[(0, ..., -2)]would index the first element on the first axis, the second-to-last element in the last axis, and include all the axes in between.>>> from numpy import arange >>> a = arange(2*3*4).reshape((2, 3, 4)) >>> a array([[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]], [[12, 13, 14, 15], [16, 17, 18, 19], [20, 21, 22, 23]]]) >>> a[0, ..., -2] array([ 2, 6, 10])
An ellipsis can go at the beginning of end of a tuple index, and is allowed to match 0 axes.
Note
Unlike the standard Python
Ellipsis,ellipsisis the type, not the object (the name is lowercase to avoid conflicting with the built-in). Useellipsis()orndindex(...)to create the object. In most ndindex contexts,...can be used instead ofellipsis(), for instance, when creating aTupleobject. Also unlikeEllipsis,ellipsis()is not singletonized, so you should not useisto compare it. See the document on type confusion for more details.- as_subindex(index)[source]¶
i.as_subindex(j)produces an indexksuch thata[j][k]gives all of the elements ofa[j]that are also ina[i].If
a[j]is a subset ofa[i], thena[j][k] == a[i]. Otherwise,a[j][k] == a[i & j], wherei & jis the intersection ofiandj, that is, the elements ofathat are indexed by bothiandj.For example, in the below diagram,
iandjindex a subset of the arraya.k = i.as_subindex(j)is an index ona[j]that gives the subset ofa[j]also included ina[i]:+------------ self ------------+ | | ------------------- a ----------------------- | | +------------- index -------------+ | | +- self.as_subindex(index) -+
i.as_subindex(j)is currently only implemented whenjis a slice with positive steps and nonnegative start and stop, or a Tuple of the same. To use it with slices with negative start or stop, callreduce()with a shape first.as_subindexcan be seen as the left-inverse of composition, that is, ifa[i] = a[j][k], thenk = i.as_subindex(j), so thatk "=" (j^-1)[i](this only works as a true inverse ifjis a subset ofi).Note that due to symmetry,
a[j][i.as_subindex(j)]anda[i][j.as_subindex(i)]will give the same subarrays ofa, which will be the array of elements indexed by botha[i]anda[j].i.as_subindex(j)may raiseValueErrorin the case that the indicesiandjdo not intersect at all.Examples
An example usage of
as_subindexis to split an index up into subindices of chunks of an array. For example, say a 1-D arrayais chunked up into chunks of sizeN, so thata[0:N],a[N:2*N],[2*N:3*N], etc. are stored separately. Then an indexa[i]can be reindexed onto the chunks viai.as_subindex(Slice(0, N)),i.as_subindex(Slice(N, 2*N)), etc.>>> from ndindex import Slice >>> i = Slice(5, 15) >>> j1 = Slice(0, 10) >>> j2 = Slice(10, 20) >>> a = list(range(20)) >>> a[i.raw] [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> a[j1.raw] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[j2.raw] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> k1 = i.as_subindex(j1) >>> k1 Slice(5, 10, 1) >>> k2 = i.as_subindex(j2) >>> k2 Slice(0, 5, 1) >>> a[j1.raw][k1.raw] [5, 6, 7, 8, 9] >>> a[j2.raw][k2.raw] [10, 11, 12, 13, 14]
See also
ndindex.ChunkSize.as_subchunksa high-level iterator that efficiently gives only those chunks that intersect with a given index
- isempty(shape=None)[source]¶
Returns whether self always indexes an empty array
An empty array is an array whose shape contains at least one 0. Note that scalars (arrays with shape
()) are not considered empty.shapecan beNone(the default), or an array shape. If it isNone, isempty() will returnTruewhenselfis always empty for any array shape. However, if it givesFalse, it could still give an empty array for some array shapes, but not all. If you know the shape of the array that will be indexed, useidx.isempty(shape)and the result will be correct for arrays of shapeshape. Ifshapeis given andselfwould raise anIndexErroron an array of shapeshape,isempty()also raisesIndexError.>>> from ndindex import Tuple, Slice >>> Tuple(0, slice(0, 1)).isempty() False >>> Tuple(0, slice(0, 0)).isempty() True >>> Slice(5, 10).isempty() False >>> Slice(5, 10).isempty(4) True
See also
- isvalid(shape)[source]¶
Check whether a given index is valid on an array of a given shape.
Returns
Trueif an array of shapeshapecan be indexed byselfandFalseif it would raiseIndexError.>>> from ndindex import ndindex >>> ndindex(3).isvalid((4,)) True >>> ndindex(3).isvalid((2,)) False
Note that some indices can never be valid and will raise a
IndexErrororTypeErrorif you attempt to construct them.>>> ndindex((..., 0, ...)) Traceback (most recent call last): ... IndexError: an index can only have a single ellipsis ('...') >>> ndindex(slice(True)) Traceback (most recent call last): ... TypeError: 'bool' object cannot be interpreted as an integer
See also
- newshape(shape)[source]¶
Returns the shape of
a[idx.raw], assumingahas shapeshape.shapeshould be a tuple of ints, or an int, which is equivalent to a 1-D shape.Raises
IndexErrorifselfwould be invalid for an array of shapeshape.>>> from ndindex import Slice, Integer, Tuple >>> shape = (6, 7, 8) >>> Integer(1).newshape(shape) (7, 8) >>> Integer(10).newshape(shape) Traceback (most recent call last): ... IndexError: index 10 is out of bounds for axis 0 with size 6 >>> Slice(2, 5).newshape(shape) (3, 7, 8) >>> Tuple(0, ..., Slice(1, 3)).newshape(shape) (7, 2)
See also
- property raw¶
Return the equivalent of
selfthat can be used as an indexNumPy does not allow custom objects to be used as indices, with the exception of integer indices, so to use an ndindex object as an index, it is necessary to use
raw.>>> from ndindex import Slice >>> import numpy as np >>> a = np.arange(5) >>> s = Slice(2, 4) >>> a[s] Traceback (most recent call last): ... IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices >>> a[s.raw] array([2, 3])
- reduce(shape=None, *, negative_int=False)[source]¶
Reduce an ellipsis index
Since an ellipsis by itself always returns the full array unchanged,
ellipsis().reduce()returnsTuple()as a canonical form (the index()also always returns an array unchanged).>>> from ndindex import ellipsis >>> ellipsis().reduce() Tuple()
- class ndindex.Newaxis[source]¶
Represents a
np.newaxis(i.e.,None) index.Newaxisadds a shape 1 dimension to the array. If aNewaxisis inside of a tuple index, it adds a shape 1 dimension at that location in the index.For example, if
ahas shape(2, 3), thena[newaxis]has shape(1, 2, 3),a[:, newaxis]has shape(2, 1, 3), and so on.>>> from ndindex import Newaxis >>> from numpy import arange >>> a = arange(0,6).reshape(2,3) >>> a[Newaxis().raw].shape (1, 2, 3) >>> a[:, Newaxis().raw, :].shape (2, 1, 3)
Using
Newaxis().rawas an index is equivalent to usingnumpy.newaxis.See newaxis for a description of the semantics of newaxis.
Note
Unlike the NumPy
newaxis,Newaxisis the type, not the object (the name is uppercase to avoid conflicting with the NumPy type). UseNewaxis(),ndindex(np.newaxis), orndindex(None)to create the object. In most ndindex contexts,np.newaxisorNonecan be used instead ofNewaxis(), for instance, when creating aTupleobject. Also unlikeNone,Newaxis()is not singletonized, so you should not useisto compare it. See the document on Type Confusion for more details.- isempty(shape=None)[source]¶
Returns whether self always indexes an empty array
An empty array is an array whose shape contains at least one 0. Note that scalars (arrays with shape
()) are not considered empty.shapecan beNone(the default), or an array shape. If it isNone, isempty() will returnTruewhenselfis always empty for any array shape. However, if it givesFalse, it could still give an empty array for some array shapes, but not all. If you know the shape of the array that will be indexed, useidx.isempty(shape)and the result will be correct for arrays of shapeshape. Ifshapeis given andselfwould raise anIndexErroron an array of shapeshape,isempty()also raisesIndexError.>>> from ndindex import Tuple, Slice >>> Tuple(0, slice(0, 1)).isempty() False >>> Tuple(0, slice(0, 0)).isempty() True >>> Slice(5, 10).isempty() False >>> Slice(5, 10).isempty(4) True
See also
- isvalid(shape)[source]¶
Check whether a given index is valid on an array of a given shape.
Returns
Trueif an array of shapeshapecan be indexed byselfandFalseif it would raiseIndexError.>>> from ndindex import ndindex >>> ndindex(3).isvalid((4,)) True >>> ndindex(3).isvalid((2,)) False
Note that some indices can never be valid and will raise a
IndexErrororTypeErrorif you attempt to construct them.>>> ndindex((..., 0, ...)) Traceback (most recent call last): ... IndexError: an index can only have a single ellipsis ('...') >>> ndindex(slice(True)) Traceback (most recent call last): ... TypeError: 'bool' object cannot be interpreted as an integer
See also
- newshape(shape)[source]¶
Returns the shape of
a[idx.raw], assumingahas shapeshape.shapeshould be a tuple of ints, or an int, which is equivalent to a 1-D shape.Raises
IndexErrorifselfwould be invalid for an array of shapeshape.>>> from ndindex import Slice, Integer, Tuple >>> shape = (6, 7, 8) >>> Integer(1).newshape(shape) (7, 8) >>> Integer(10).newshape(shape) Traceback (most recent call last): ... IndexError: index 10 is out of bounds for axis 0 with size 6 >>> Slice(2, 5).newshape(shape) (3, 7, 8) >>> Tuple(0, ..., Slice(1, 3)).newshape(shape) (7, 2)
See also
- property raw¶
Return the equivalent of
selfthat can be used as an indexNumPy does not allow custom objects to be used as indices, with the exception of integer indices, so to use an ndindex object as an index, it is necessary to use
raw.>>> from ndindex import Slice >>> import numpy as np >>> a = np.arange(5) >>> s = Slice(2, 4) >>> a[s] Traceback (most recent call last): ... IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices >>> a[s.raw] array([2, 3])
- class ndindex.Tuple[source]¶
Represents a tuple of single-axis indices.
Valid single axis indices are
See Tuple Indices for a description of the semantics of tuple indices.
Tuple(x1, x2, …, xn)represents the indexa[x1, x2, …, xn]or, equivalently,a[(x1, x2, …, xn)].Tuple()with no arguments is the empty tuple index,a[()], which returnsaunchanged.>>> from ndindex import Tuple, Slice >>> import numpy as np >>> idx = Tuple(0, Slice(2, 4)) >>> a = np.arange(10).reshape((2, 5)) >>> a array([[0, 1, 2, 3, 4], [5, 6, 7, 8, 9]]) >>> a[0, 2:4] array([2, 3]) >>> a[idx.raw] array([2, 3])
Note
Tupledoes not represent a tuple, but rather an tuple index. It does not have most methods thattuplehas, and should not be used in non-indexing contexts. See the document on Type Confusion for more details.- as_subindex(index)[source]¶
i.as_subindex(j)produces an indexksuch thata[j][k]gives all of the elements ofa[j]that are also ina[i].If
a[j]is a subset ofa[i], thena[j][k] == a[i]. Otherwise,a[j][k] == a[i & j], wherei & jis the intersection ofiandj, that is, the elements ofathat are indexed by bothiandj.For example, in the below diagram,
iandjindex a subset of the arraya.k = i.as_subindex(j)is an index ona[j]that gives the subset ofa[j]also included ina[i]:+------------ self ------------+ | | ------------------- a ----------------------- | | +------------- index -------------+ | | +- self.as_subindex(index) -+
i.as_subindex(j)is currently only implemented whenjis a slice with positive steps and nonnegative start and stop, or a Tuple of the same. To use it with slices with negative start or stop, callreduce()with a shape first.as_subindexcan be seen as the left-inverse of composition, that is, ifa[i] = a[j][k], thenk = i.as_subindex(j), so thatk "=" (j^-1)[i](this only works as a true inverse ifjis a subset ofi).Note that due to symmetry,
a[j][i.as_subindex(j)]anda[i][j.as_subindex(i)]will give the same subarrays ofa, which will be the array of elements indexed by botha[i]anda[j].i.as_subindex(j)may raiseValueErrorin the case that the indicesiandjdo not intersect at all.Examples
An example usage of
as_subindexis to split an index up into subindices of chunks of an array. For example, say a 1-D arrayais chunked up into chunks of sizeN, so thata[0:N],a[N:2*N],[2*N:3*N], etc. are stored separately. Then an indexa[i]can be reindexed onto the chunks viai.as_subindex(Slice(0, N)),i.as_subindex(Slice(N, 2*N)), etc.>>> from ndindex import Slice >>> i = Slice(5, 15) >>> j1 = Slice(0, 10) >>> j2 = Slice(10, 20) >>> a = list(range(20)) >>> a[i.raw] [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> a[j1.raw] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[j2.raw] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> k1 = i.as_subindex(j1) >>> k1 Slice(5, 10, 1) >>> k2 = i.as_subindex(j2) >>> k2 Slice(0, 5, 1) >>> a[j1.raw][k1.raw] [5, 6, 7, 8, 9] >>> a[j2.raw][k2.raw] [10, 11, 12, 13, 14]
See also
ndindex.ChunkSize.as_subchunksa high-level iterator that efficiently gives only those chunks that intersect with a given index
- broadcast_arrays()[source]¶
Broadcast all the array indices in self to a common shape and convert boolean array indices into integer array indices.
The resulting index is equivalent in all contexts where the original index is allowed. However, it is possible for the original index to give an IndexError but for the new index to not, since integer array indices have less stringent shape requirements than boolean array indices. There are also some instances for empty indices (
isemptyis True) where bounds would be checked before broadcasting but not after.Any
BooleanArrayindices are converted toIntegerArrayindices. Furthermore, if there areBooleanArrayorIntegerArrayindices, then anyIntegerindices are also converted into scalarIntegerArrayindices and broadcast. Furthermore, if there are multiple boolean scalar indices (TrueorFalse), they are combined into a single one.Note that array broadcastability is checked in the
Tupleconstructor, so this method will not raise any exceptions.This is part of what is performed by
expand, but unlikeexpand, this method does not do any other manipulations, and it does not require a shape.>>> from ndindex import Tuple >>> idx = Tuple([[False], [True], [True]], [[4], [5], [5]], -1) >>> print(idx.broadcast_arrays()) Tuple(IntegerArray([[1 2] [1 2] [1 2]]), IntegerArray([[0 0] [0 0] [0 0]]), IntegerArray([[4 4] [5 5] [5 5]]), IntegerArray([[-1 -1] [-1 -1] [-1 -1]]))
See also
- property ellipsis_index¶
Give the index i of
self.argswhere the ellipsis is.If
selfdoesn’t have an ellipsis, it giveslen(self.args), since tuple indices without an ellipsis always implicitly end in an ellipsis.The resulting value
iis such thatself.args[:i]indexes the beginning axes of an array andself.args[i+1:]indexes the end axes of an array.>>> from ndindex import Tuple >>> idx = Tuple(0, 1, ..., 2, 3) >>> i = idx.ellipsis_index >>> i 2 >>> idx.args[:i] (Integer(0), Integer(1)) >>> idx.args[i+1:] (Integer(2), Integer(3))
>>> Tuple(0, 1).ellipsis_index 2
- expand(shape)[source]¶
Expand a Tuple index on an array of shape
shapeAn expanded index is as explicit as possible. Unlike
reduce, which tries to simplify an index and remove redundancies,expand()typically makes an index larger.If
selfis invalid for the given shape, anIndexErroris raised. Otherwise, the returned index satisfies the following:It is always a
Tuple.The length of the
.argsis equal to the length of the shape plus the number ofNewaxisindices inselfplus 1 if there is a scalarBooleanArray(TrueorFalse).The resulting
Tuplehas noellipses. If there are axes that would be matched by an ellipsis or an implicit ellipsis at the end of the tuple,Slice(0, n, 1)indices are inserted, wherenis the corresponding axis of theshape.Any array indices in
selfare broadcast together. Ifselfcontains array indices (IntegerArrayorBooleanArray), then anyIntegerindices are converted intoIntegerArrayindices of shape()and broadcast. Note that broadcasting is done in a memory efficient way so that even if the broadcasted shape is large it will not take up more memory than the original.Scalar
BooleanArrayarguments (TrueorFalse) are combined into a single term (the same as withTuple.reduce()).Non-scalar
BooleanArrays are all converted into equivalentIntegerArrays vianonzero()and broadcasted.
>>> from ndindex import Tuple, Slice >>> Slice(None).expand((2, 3)) Tuple(slice(0, 2, 1), slice(0, 3, 1))
>>> idx = Tuple(slice(0, 10), ..., None, -3) >>> idx.expand((5, 3)) Tuple(slice(0, 5, 1), None, 0) >>> idx.expand((1, 2, 3)) Tuple(slice(0, 1, 1), slice(0, 2, 1), None, 0) >>> idx.expand((5,)) Traceback (most recent call last): ... IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed >>> idx.expand((5, 2)) Traceback (most recent call last): ... IndexError: index -3 is out of bounds for axis 1 with size 2
>>> idx = Tuple(..., [0, 1], -1) >>> idx.expand((1, 2, 3)) Tuple(slice(0, 1, 1), [0, 1], [2, 2])
See also
- property has_ellipsis¶
Returns True if self has an ellipsis
- isempty(shape=None)[source]¶
Returns whether self always indexes an empty array
An empty array is an array whose shape contains at least one 0. Note that scalars (arrays with shape
()) are not considered empty.shapecan beNone(the default), or an array shape. If it isNone, isempty() will returnTruewhenselfis always empty for any array shape. However, if it givesFalse, it could still give an empty array for some array shapes, but not all. If you know the shape of the array that will be indexed, useidx.isempty(shape)and the result will be correct for arrays of shapeshape. Ifshapeis given andselfwould raise anIndexErroron an array of shapeshape,isempty()also raisesIndexError.>>> from ndindex import Tuple, Slice >>> Tuple(0, slice(0, 1)).isempty() False >>> Tuple(0, slice(0, 0)).isempty() True >>> Slice(5, 10).isempty() False >>> Slice(5, 10).isempty(4) True
See also
- newshape(shape)[source]¶
Returns the shape of
a[idx.raw], assumingahas shapeshape.shapeshould be a tuple of ints, or an int, which is equivalent to a 1-D shape.Raises
IndexErrorifselfwould be invalid for an array of shapeshape.>>> from ndindex import Slice, Integer, Tuple >>> shape = (6, 7, 8) >>> Integer(1).newshape(shape) (7, 8) >>> Integer(10).newshape(shape) Traceback (most recent call last): ... IndexError: index 10 is out of bounds for axis 0 with size 6 >>> Slice(2, 5).newshape(shape) (3, 7, 8) >>> Tuple(0, ..., Slice(1, 3)).newshape(shape) (7, 2)
See also
- reduce(shape=None, *, negative_int=False)[source]¶
Reduce a Tuple index on an array of shape
shapeA
Tuplewith a single argument is always reduced to that single argument (becausea[idx,]is the same asa[idx]).>>> from ndindex import Tuple
>>> Tuple(slice(2, 4)).reduce() Slice(2, 4, 1)
If an explicit array shape is given, the result will either be
IndexErrorif the index is invalid for the given shape, or an index that is as simple as possible:Any axes that can be merged into an
ellipsisare removed. This includes the implicit ellipsis at the end of a Tuple that doesn’t contain any explicit ellipses.Ellipsesthat don’t match any axes are removed.Scalar
BooleanArrayarguments (TrueorFalse) are combined into a single term (the first boolean scalar is replaced with the AND of all the boolean scalars).If the resulting
Tuplewould have a single argument, that argument is returned.
>>> idx = Tuple(0, ..., slice(0, 3)) >>> idx.reduce((5, 4)) Tuple(0, slice(0, 3, 1)) >>> idx.reduce((5, 3)) Integer(0)
>>> idx = Tuple(slice(0, 10), -3) >>> idx.reduce((5,)) Traceback (most recent call last): ... IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed >>> idx.reduce((5, 2)) Traceback (most recent call last): ... IndexError: index -3 is out of bounds for axis 1 with size 2
Note
ndindex presently does not distinguish between scalar objects and 0-D arrays. It is possible for the original index to produce one and the reduced index to produce the other. In particular, the presence of a redundant ellipsis forces NumPy to return a 0-D array instead of a scalar.
>>> import numpy as np >>> a = np.array([0, 1]) >>> Tuple(..., 1).reduce(a.shape) Integer(1) >>> a[..., 1] array(1) >>> a[1] np.int64(1)
- selected_indices(shape)[source]¶
Return an iterator over all indices that are selected by
selfon an array of shapeshape.The result is a set of indices
isuch that[a[i] for i in idx.selected_indices(a.shape)]is all the elements ofa[idx]. The indices are all iterated over in C (i.e., row major) order.>>> from ndindex import Slice, Tuple >>> idx = Slice(5, 10) >>> list(idx.selected_indices(20)) [Integer(5), Integer(6), Integer(7), Integer(8), Integer(9)] >>> idx = Tuple(Slice(5, 10), Slice(0, 2)) >>> list(idx.selected_indices((20, 3))) [Tuple(5, 0), Tuple(5, 1), Tuple(6, 0), Tuple(6, 1), Tuple(7, 0), Tuple(7, 1), Tuple(8, 0), Tuple(8, 1), Tuple(9, 0), Tuple(9, 1)]
To correspond these indices to the elements of
a[idx], you can useiter_indices(idx.newshape(shape)), since both iterators iterate the indices in C order.>>> from ndindex import iter_indices >>> idx = Tuple(Slice(3, 5), Slice(0, 2)) >>> shape = (5, 5) >>> import numpy as np >>> a = np.arange(25).reshape(shape) >>> for a_idx, (new_idx,) in zip( ... idx.selected_indices(shape), ... iter_indices(idx.newshape(shape))): ... print(a_idx, new_idx, a[a_idx.raw], a[idx.raw][new_idx.raw]) Tuple(3, 0) Tuple(0, 0) 15 15 Tuple(3, 1) Tuple(0, 1) 16 16 Tuple(4, 0) Tuple(1, 0) 20 20 Tuple(4, 1) Tuple(1, 1) 21 21
See also
ndindex.iter_indicesAn iterator of indices to select every element for arrays of a given shape.
ndindex.ChunkSize.as_subchunksA high-level iterator that efficiently gives only those chunks that intersect with a given index
- class ndindex.IntegerArray(idx, shape=None, _copy=True)[source]¶
Represents an integer array index.
If
idxis an n-dimensional integer array with shapes = (s1, ..., sn)andais any array,a[idx]replaces the first dimension ofawith dimensions of sizes1, ..., sn, where each entry is indexed according to the entry inidxas an integer index.Integer arrays can also appear as part of tuple indices. In that case, they replace the axis being indexed. If more than one integer array appears inside of a tuple index, they are broadcast together and iterated as one. Furthermore, if an integer array appears in a tuple index, all integer indices in the tuple are treated as scalar integer arrays and are also broadcast. In general, an
Integerindex semantically behaves the same as a scalar (shape=())IntegerArray.A list (or list of lists) of integers may also be used in place of an array.
See Integer Array Indices for a description of the semantics of integer array indices.
>>> from ndindex import IntegerArray >>> import numpy as np >>> idx = IntegerArray([[0, 1], [1, 2]]) >>> a = np.arange(10) >>> a[idx.raw] array([[0, 1], [1, 2]])
Note
IntegerArraydoes not represent an array, but rather an array index. It does not have most methods thatnumpy.ndarrayhas, and should not be used in array contexts. See the document on Type Confusion for more details.- dtype¶
The dtype of
IntegerArrayisnp.intp, which is typically eithernp.int32ornp.int64depending on the platform.
- args¶
idx.argscontains the arguments needed to createidx.For an ndindex object
idx,idx.argsis always a tuple such thattype(idx)(*idx.args) == idx
For
Tupleindices, the elements of.argsare themselves ndindex types. For other types,.argscontains raw Python types. Note that.argscontains NumPy arrays forIntegerArrayandBooleanArraytypes, so one should always do equality testing or hashing on the ndindex type itself, not its.args.
- property array¶
Return the NumPy array of self.
This is the same as
self.args[0].>>> from ndindex import IntegerArray, BooleanArray >>> IntegerArray([0, 1]).array array([0, 1]) >>> BooleanArray([False, True]).array array([False, True])
- as_subindex(index)[source]¶
i.as_subindex(j)produces an indexksuch thata[j][k]gives all of the elements ofa[j]that are also ina[i].If
a[j]is a subset ofa[i], thena[j][k] == a[i]. Otherwise,a[j][k] == a[i & j], wherei & jis the intersection ofiandj, that is, the elements ofathat are indexed by bothiandj.For example, in the below diagram,
iandjindex a subset of the arraya.k = i.as_subindex(j)is an index ona[j]that gives the subset ofa[j]also included ina[i]:+------------ self ------------+ | | ------------------- a ----------------------- | | +------------- index -------------+ | | +- self.as_subindex(index) -+
i.as_subindex(j)is currently only implemented whenjis a slice with positive steps and nonnegative start and stop, or a Tuple of the same. To use it with slices with negative start or stop, callreduce()with a shape first.as_subindexcan be seen as the left-inverse of composition, that is, ifa[i] = a[j][k], thenk = i.as_subindex(j), so thatk "=" (j^-1)[i](this only works as a true inverse ifjis a subset ofi).Note that due to symmetry,
a[j][i.as_subindex(j)]anda[i][j.as_subindex(i)]will give the same subarrays ofa, which will be the array of elements indexed by botha[i]anda[j].i.as_subindex(j)may raiseValueErrorin the case that the indicesiandjdo not intersect at all.Examples
An example usage of
as_subindexis to split an index up into subindices of chunks of an array. For example, say a 1-D arrayais chunked up into chunks of sizeN, so thata[0:N],a[N:2*N],[2*N:3*N], etc. are stored separately. Then an indexa[i]can be reindexed onto the chunks viai.as_subindex(Slice(0, N)),i.as_subindex(Slice(N, 2*N)), etc.>>> from ndindex import Slice >>> i = Slice(5, 15) >>> j1 = Slice(0, 10) >>> j2 = Slice(10, 20) >>> a = list(range(20)) >>> a[i.raw] [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> a[j1.raw] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[j2.raw] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> k1 = i.as_subindex(j1) >>> k1 Slice(5, 10, 1) >>> k2 = i.as_subindex(j2) >>> k2 Slice(0, 5, 1) >>> a[j1.raw][k1.raw] [5, 6, 7, 8, 9] >>> a[j2.raw][k2.raw] [10, 11, 12, 13, 14]
See also
ndindex.ChunkSize.as_subchunksa high-level iterator that efficiently gives only those chunks that intersect with a given index
- broadcast_arrays()[source]¶
Broadcast all the array indices in self to a common shape and convert boolean array indices into integer array indices.
The resulting index is equivalent in all contexts where the original index is allowed. However, it is possible for the original index to give an IndexError but for the new index to not, since integer array indices have less stringent shape requirements than boolean array indices. There are also some instances for empty indices (
isemptyis True) where bounds would be checked before broadcasting but not after.Any
BooleanArrayindices are converted toIntegerArrayindices. Furthermore, if there areBooleanArrayorIntegerArrayindices, then anyIntegerindices are also converted into scalarIntegerArrayindices and broadcast. Furthermore, if there are multiple boolean scalar indices (TrueorFalse), they are combined into a single one.Note that array broadcastability is checked in the
Tupleconstructor, so this method will not raise any exceptions.This is part of what is performed by
expand, but unlikeexpand, this method does not do any other manipulations, and it does not require a shape.>>> from ndindex import Tuple >>> idx = Tuple([[False], [True], [True]], [[4], [5], [5]], -1) >>> print(idx.broadcast_arrays()) Tuple(IntegerArray([[1 2] [1 2] [1 2]]), IntegerArray([[0 0] [0 0] [0 0]]), IntegerArray([[4 4] [5 5] [5 5]]), IntegerArray([[-1 -1] [-1 -1] [-1 -1]]))
See also
- expand(shape)[source]¶
Expand a Tuple index on an array of shape
shapeAn expanded index is as explicit as possible. Unlike
reduce, which tries to simplify an index and remove redundancies,expand()typically makes an index larger.If
selfis invalid for the given shape, anIndexErroris raised. Otherwise, the returned index satisfies the following:It is always a
Tuple.The length of the
.argsis equal to the length of the shape plus the number ofNewaxisindices inselfplus 1 if there is a scalarBooleanArray(TrueorFalse).The resulting
Tuplehas noellipses. If there are axes that would be matched by an ellipsis or an implicit ellipsis at the end of the tuple,Slice(0, n, 1)indices are inserted, wherenis the corresponding axis of theshape.Any array indices in
selfare broadcast together. Ifselfcontains array indices (IntegerArrayorBooleanArray), then anyIntegerindices are converted intoIntegerArrayindices of shape()and broadcast. Note that broadcasting is done in a memory efficient way so that even if the broadcasted shape is large it will not take up more memory than the original.Scalar
BooleanArrayarguments (TrueorFalse) are combined into a single term (the same as withTuple.reduce()).Non-scalar
BooleanArrays are all converted into equivalentIntegerArrays vianonzero()and broadcasted.
>>> from ndindex import Tuple, Slice >>> Slice(None).expand((2, 3)) Tuple(slice(0, 2, 1), slice(0, 3, 1))
>>> idx = Tuple(slice(0, 10), ..., None, -3) >>> idx.expand((5, 3)) Tuple(slice(0, 5, 1), None, 0) >>> idx.expand((1, 2, 3)) Tuple(slice(0, 1, 1), slice(0, 2, 1), None, 0) >>> idx.expand((5,)) Traceback (most recent call last): ... IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed >>> idx.expand((5, 2)) Traceback (most recent call last): ... IndexError: index -3 is out of bounds for axis 1 with size 2
>>> idx = Tuple(..., [0, 1], -1) >>> idx.expand((1, 2, 3)) Tuple(slice(0, 1, 1), [0, 1], [2, 2])
See also
- isempty(shape=None)[source]¶
Returns whether self always indexes an empty array
An empty array is an array whose shape contains at least one 0. Note that scalars (arrays with shape
()) are not considered empty.shapecan beNone(the default), or an array shape. If it isNone, isempty() will returnTruewhenselfis always empty for any array shape. However, if it givesFalse, it could still give an empty array for some array shapes, but not all. If you know the shape of the array that will be indexed, useidx.isempty(shape)and the result will be correct for arrays of shapeshape. Ifshapeis given andselfwould raise anIndexErroron an array of shapeshape,isempty()also raisesIndexError.>>> from ndindex import Tuple, Slice >>> Tuple(0, slice(0, 1)).isempty() False >>> Tuple(0, slice(0, 0)).isempty() True >>> Slice(5, 10).isempty() False >>> Slice(5, 10).isempty(4) True
See also
- isvalid(shape, _axis=0)[source]¶
Check whether a given index is valid on an array of a given shape.
Returns
Trueif an array of shapeshapecan be indexed byselfandFalseif it would raiseIndexError.>>> from ndindex import ndindex >>> ndindex(3).isvalid((4,)) True >>> ndindex(3).isvalid((2,)) False
Note that some indices can never be valid and will raise a
IndexErrororTypeErrorif you attempt to construct them.>>> ndindex((..., 0, ...)) Traceback (most recent call last): ... IndexError: an index can only have a single ellipsis ('...') >>> ndindex(slice(True)) Traceback (most recent call last): ... TypeError: 'bool' object cannot be interpreted as an integer
See also
- property ndim¶
Return the number of dimensions of the array of self.
This is the same as
self.array.ndim. Note that this is not the same as the number of dimensions of an array that is indexed byself. Uselenonnewshape()to get that.>>> from ndindex import IntegerArray, BooleanArray >>> IntegerArray([[0], [1]]).ndim 2 >>> BooleanArray([[False], [True]]).ndim 2
- newshape(shape)[source]¶
Returns the shape of
a[idx.raw], assumingahas shapeshape.shapeshould be a tuple of ints, or an int, which is equivalent to a 1-D shape.Raises
IndexErrorifselfwould be invalid for an array of shapeshape.>>> from ndindex import Slice, Integer, Tuple >>> shape = (6, 7, 8) >>> Integer(1).newshape(shape) (7, 8) >>> Integer(10).newshape(shape) Traceback (most recent call last): ... IndexError: index 10 is out of bounds for axis 0 with size 6 >>> Slice(2, 5).newshape(shape) (3, 7, 8) >>> Tuple(0, ..., Slice(1, 3)).newshape(shape) (7, 2)
See also
- property raw¶
Return the equivalent of
selfthat can be used as an indexNumPy does not allow custom objects to be used as indices, with the exception of integer indices, so to use an ndindex object as an index, it is necessary to use
raw.>>> from ndindex import Slice >>> import numpy as np >>> a = np.arange(5) >>> s = Slice(2, 4) >>> a[s] Traceback (most recent call last): ... IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices >>> a[s.raw] array([2, 3])
- reduce(shape=None, *, axis=0, negative_int=False)[source]¶
Reduce an
IntegerArrayindex on an array of shapeshape.The result will either be
IndexErrorif the index is invalid for the given shape, anIntegerArrayindex where the values are all nonnegative, or, ifselfis a scalar array index (self.shape == ()), anIntegerwhose value is nonnegative.If
negative_intisTrueand ashapeis provided, the result will be anIntegerArraywith negative entries instead of positive entries.>>> from ndindex import IntegerArray >>> idx = IntegerArray([-5, 2]) >>> idx.reduce((3,)) Traceback (most recent call last): ... IndexError: index -5 is out of bounds for axis 0 with size 3 >>> idx.reduce((9,)) IntegerArray([4, 2]) >>> idx.reduce((9,), negative_int=True) IntegerArray([-5, -7])
- selected_indices(shape, axis=None)[source]¶
Return an iterator over all indices that are selected by
selfon an array of shapeshape.The result is a set of indices
isuch that[a[i] for i in idx.selected_indices(a.shape)]is all the elements ofa[idx]. The indices are all iterated over in C (i.e., row major) order.>>> from ndindex import Slice, Tuple >>> idx = Slice(5, 10) >>> list(idx.selected_indices(20)) [Integer(5), Integer(6), Integer(7), Integer(8), Integer(9)] >>> idx = Tuple(Slice(5, 10), Slice(0, 2)) >>> list(idx.selected_indices((20, 3))) [Tuple(5, 0), Tuple(5, 1), Tuple(6, 0), Tuple(6, 1), Tuple(7, 0), Tuple(7, 1), Tuple(8, 0), Tuple(8, 1), Tuple(9, 0), Tuple(9, 1)]
To correspond these indices to the elements of
a[idx], you can useiter_indices(idx.newshape(shape)), since both iterators iterate the indices in C order.>>> from ndindex import iter_indices >>> idx = Tuple(Slice(3, 5), Slice(0, 2)) >>> shape = (5, 5) >>> import numpy as np >>> a = np.arange(25).reshape(shape) >>> for a_idx, (new_idx,) in zip( ... idx.selected_indices(shape), ... iter_indices(idx.newshape(shape))): ... print(a_idx, new_idx, a[a_idx.raw], a[idx.raw][new_idx.raw]) Tuple(3, 0) Tuple(0, 0) 15 15 Tuple(3, 1) Tuple(0, 1) 16 16 Tuple(4, 0) Tuple(1, 0) 20 20 Tuple(4, 1) Tuple(1, 1) 21 21
See also
ndindex.iter_indicesAn iterator of indices to select every element for arrays of a given shape.
ndindex.ChunkSize.as_subchunksA high-level iterator that efficiently gives only those chunks that intersect with a given index
- property shape¶
Return the shape of the array of self.
This is the same as
self.array.shape. Note that this is not the same as the shape of an array that is indexed byself. Usenewshape()to get that.>>> from ndindex import IntegerArray, BooleanArray >>> IntegerArray([[0], [1]]).shape (2, 1) >>> BooleanArray([[False], [True]]).shape (2, 1)
- property size¶
Return the number of elements of the array of self.
This is the same as
self.array.size. Note that this is not the same as the number of elements of an array that is indexed byself. Usenp.prodonnewshape()to get that.>>> from ndindex import IntegerArray, BooleanArray >>> IntegerArray([[0], [1]]).size 2 >>> BooleanArray([[False], [True]]).size 2
- class ndindex.BooleanArray(idx, shape=None, _copy=True)[source]¶
Represents a boolean array index (also known as a mask).
If
idxis an n-dimensional boolean array with shapes = (s1, ..., sn)andais an array of shapes = (s1, ..., sn, ..., sm),a[idx]replaces the firstndimensions ofawith a single dimensions of sizenp.nonzero(idx), where each entry is included if the corresponding element ofidxis True. The axes in the index shape should match the corresponding axes in the array shape or be 0, or the index produces IndexError.The typical way of creating a mask is to use boolean operations on an array, then index the array with that. For example, if
ais an array of integers,a[a > 0]will produces a flat array of the elements ofathat are positive.Some important things to note about boolean array index semantics:
A boolean array index will remove as many dimensions as the index has, and replace them with a single flat dimension which is the size of the number of
Trueelements in the index.A boolean array index
idxworks the same as the integer array indexnp.nonzero(idx). In particular, the elements of the index are always iterated in row-major, C-style order. This does not apply to 0-dimensional boolean indices.A 0-dimensional boolean index (i.e., just the scalar
TrueorFalse) can still be thought of as removing 0 dimensions and adding a single dimension of length 1 for True or 0 for False. Hence, ifahas shape(s1, ..., sn), thena[True]has shape(1, s1, ..., sn), anda[False]has shape(0, s1, ..., sn).If a tuple index has multiple boolean arrays, they are broadcast together and iterated as a single array, similar to
IntegerArray. If a boolean array indexidxis mixed with an integer array index in a tuple index, it is treated likenp.nonzero(idx).
See Boolean Array Indices for a more complete description of the semantics of boolean array indices.
A list (or list of lists) of booleans may also be used in place of an array.
>>> from ndindex import BooleanArray >>> import numpy as np >>> idx = BooleanArray([[ True, True], ... [ True, False], ... [False, False], ... [False, True], ... [False, False]]) >>> a = np.arange(10).reshape((5, 2)) >>> a[idx.raw] array([0, 1, 2, 7])
Note
BooleanArraydoes not represent an array, but rather an array index. It does not have most methods thatnumpy.ndarrayhas, and should not be used in array contexts. See the document on Type Confusion for more details.- dtype¶
The dtype of
BooleanArrayisnp.bool_.
- args¶
idx.argscontains the arguments needed to createidx.For an ndindex object
idx,idx.argsis always a tuple such thattype(idx)(*idx.args) == idx
For
Tupleindices, the elements of.argsare themselves ndindex types. For other types,.argscontains raw Python types. Note that.argscontains NumPy arrays forIntegerArrayandBooleanArraytypes, so one should always do equality testing or hashing on the ndindex type itself, not its.args.
- property array¶
Return the NumPy array of self.
This is the same as
self.args[0].>>> from ndindex import IntegerArray, BooleanArray >>> IntegerArray([0, 1]).array array([0, 1]) >>> BooleanArray([False, True]).array array([False, True])
- as_subindex(index)[source]¶
i.as_subindex(j)produces an indexksuch thata[j][k]gives all of the elements ofa[j]that are also ina[i].If
a[j]is a subset ofa[i], thena[j][k] == a[i]. Otherwise,a[j][k] == a[i & j], wherei & jis the intersection ofiandj, that is, the elements ofathat are indexed by bothiandj.For example, in the below diagram,
iandjindex a subset of the arraya.k = i.as_subindex(j)is an index ona[j]that gives the subset ofa[j]also included ina[i]:+------------ self ------------+ | | ------------------- a ----------------------- | | +------------- index -------------+ | | +- self.as_subindex(index) -+
i.as_subindex(j)is currently only implemented whenjis a slice with positive steps and nonnegative start and stop, or a Tuple of the same. To use it with slices with negative start or stop, callreduce()with a shape first.as_subindexcan be seen as the left-inverse of composition, that is, ifa[i] = a[j][k], thenk = i.as_subindex(j), so thatk "=" (j^-1)[i](this only works as a true inverse ifjis a subset ofi).Note that due to symmetry,
a[j][i.as_subindex(j)]anda[i][j.as_subindex(i)]will give the same subarrays ofa, which will be the array of elements indexed by botha[i]anda[j].i.as_subindex(j)may raiseValueErrorin the case that the indicesiandjdo not intersect at all.Examples
An example usage of
as_subindexis to split an index up into subindices of chunks of an array. For example, say a 1-D arrayais chunked up into chunks of sizeN, so thata[0:N],a[N:2*N],[2*N:3*N], etc. are stored separately. Then an indexa[i]can be reindexed onto the chunks viai.as_subindex(Slice(0, N)),i.as_subindex(Slice(N, 2*N)), etc.>>> from ndindex import Slice >>> i = Slice(5, 15) >>> j1 = Slice(0, 10) >>> j2 = Slice(10, 20) >>> a = list(range(20)) >>> a[i.raw] [5, 6, 7, 8, 9, 10, 11, 12, 13, 14] >>> a[j1.raw] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> a[j2.raw] [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> k1 = i.as_subindex(j1) >>> k1 Slice(5, 10, 1) >>> k2 = i.as_subindex(j2) >>> k2 Slice(0, 5, 1) >>> a[j1.raw][k1.raw] [5, 6, 7, 8, 9] >>> a[j2.raw][k2.raw] [10, 11, 12, 13, 14]
See also
ndindex.ChunkSize.as_subchunksa high-level iterator that efficiently gives only those chunks that intersect with a given index
- broadcast_arrays()[source]¶
Broadcast all the array indices in self to a common shape and convert boolean array indices into integer array indices.
The resulting index is equivalent in all contexts where the original index is allowed. However, it is possible for the original index to give an IndexError but for the new index to not, since integer array indices have less stringent shape requirements than boolean array indices. There are also some instances for empty indices (
isemptyis True) where bounds would be checked before broadcasting but not after.Any
BooleanArrayindices are converted toIntegerArrayindices. Furthermore, if there areBooleanArrayorIntegerArrayindices, then anyIntegerindices are also converted into scalarIntegerArrayindices and broadcast. Furthermore, if there are multiple boolean scalar indices (TrueorFalse), they are combined into a single one.Note that array broadcastability is checked in the
Tupleconstructor, so this method will not raise any exceptions.This is part of what is performed by
expand, but unlikeexpand, this method does not do any other manipulations, and it does not require a shape.>>> from ndindex import Tuple >>> idx = Tuple([[False], [True], [True]], [[4], [5], [5]], -1) >>> print(idx.broadcast_arrays()) Tuple(IntegerArray([[1 2] [1 2] [1 2]]), IntegerArray([[0 0] [0 0] [0 0]]), IntegerArray([[4 4] [5 5] [5 5]]), IntegerArray([[-1 -1] [-1 -1] [-1 -1]]))
See also
- property count_nonzero¶
Returns the number of elements indexed by self.
In general, if shapes match, when indexed by
self, the first n dimensions of an array are replaced with a single dimension of sizecount_nonzero, where n isself.shape.This is the same as
np.count_nonzero(self.array). Note, to get the shape of an array indexed by self, usenewshape(), not this method.>>> from ndindex import BooleanArray >>> BooleanArray([True, False, True]).count_nonzero 2
- expand(shape)[source]¶
Expand a Tuple index on an array of shape
shapeAn expanded index is as explicit as possible. Unlike
reduce, which tries to simplify an index and remove redundancies,expand()typically makes an index larger.If
selfis invalid for the given shape, anIndexErroris raised. Otherwise, the returned index satisfies the following:It is always a
Tuple.The length of the
.argsis equal to the length of the shape plus the number ofNewaxisindices inselfplus 1 if there is a scalarBooleanArray(TrueorFalse).The resulting
Tuplehas noellipses. If there are axes that would be matched by an ellipsis or an implicit ellipsis at the end of the tuple,Slice(0, n, 1)indices are inserted, wherenis the corresponding axis of theshape.Any array indices in
selfare broadcast together. Ifselfcontains array indices (IntegerArrayorBooleanArray), then anyIntegerindices are converted intoIntegerArrayindices of shape()and broadcast. Note that broadcasting is done in a memory efficient way so that even if the broadcasted shape is large it will not take up more memory than the original.Scalar
BooleanArrayarguments (TrueorFalse) are combined into a single term (the same as withTuple.reduce()).Non-scalar
BooleanArrays are all converted into equivalentIntegerArrays vianonzero()and broadcasted.
>>> from ndindex import Tuple, Slice >>> Slice(None).expand((2, 3)) Tuple(slice(0, 2, 1), slice(0, 3, 1))
>>> idx = Tuple(slice(0, 10), ..., None, -3) >>> idx.expand((5, 3)) Tuple(slice(0, 5, 1), None, 0) >>> idx.expand((1, 2, 3)) Tuple(slice(0, 1, 1), slice(0, 2, 1), None, 0) >>> idx.expand((5,)) Traceback (most recent call last): ... IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed >>> idx.expand((5, 2)) Traceback (most recent call last): ... IndexError: index -3 is out of bounds for axis 1 with size 2
>>> idx = Tuple(..., [0, 1], -1) >>> idx.expand((1, 2, 3)) Tuple(slice(0, 1, 1), [0, 1], [2, 2])
See also
- isempty(shape=None)[source]¶
Returns whether self always indexes an empty array
An empty array is an array whose shape contains at least one 0. Note that scalars (arrays with shape
()) are not considered empty.shapecan beNone(the default), or an array shape. If it isNone, isempty() will returnTruewhenselfis always empty for any array shape. However, if it givesFalse, it could still give an empty array for some array shapes, but not all. If you know the shape of the array that will be indexed, useidx.isempty(shape)and the result will be correct for arrays of shapeshape. Ifshapeis given andselfwould raise anIndexErroron an array of shapeshape,isempty()also raisesIndexError.>>> from ndindex import Tuple, Slice >>> Tuple(0, slice(0, 1)).isempty() False >>> Tuple(0, slice(0, 0)).isempty() True >>> Slice(5, 10).isempty() False >>> Slice(5, 10).isempty(4) True
See also
- isvalid(shape, _axis=0)[source]¶
Check whether a given index is valid on an array of a given shape.
Returns
Trueif an array of shapeshapecan be indexed byselfandFalseif it would raiseIndexError.>>> from ndindex import ndindex >>> ndindex(3).isvalid((4,)) True >>> ndindex(3).isvalid((2,)) False
Note that some indices can never be valid and will raise a
IndexErrororTypeErrorif you attempt to construct them.>>> ndindex((..., 0, ...)) Traceback (most recent call last): ... IndexError: an index can only have a single ellipsis ('...') >>> ndindex(slice(True)) Traceback (most recent call last): ... TypeError: 'bool' object cannot be interpreted as an integer
See also
- property ndim¶
Return the number of dimensions of the array of self.
This is the same as
self.array.ndim. Note that this is not the same as the number of dimensions of an array that is indexed byself. Uselenonnewshape()to get that.>>> from ndindex import IntegerArray, BooleanArray >>> IntegerArray([[0], [1]]).ndim 2 >>> BooleanArray([[False], [True]]).ndim 2
- newshape(shape)[source]¶
Returns the shape of
a[idx.raw], assumingahas shapeshape.shapeshould be a tuple of ints, or an int, which is equivalent to a 1-D shape.Raises
IndexErrorifselfwould be invalid for an array of shapeshape.>>> from ndindex import Slice, Integer, Tuple >>> shape = (6, 7, 8) >>> Integer(1).newshape(shape) (7, 8) >>> Integer(10).newshape(shape) Traceback (most recent call last): ... IndexError: index 10 is out of bounds for axis 0 with size 6 >>> Slice(2, 5).newshape(shape) (3, 7, 8) >>> Tuple(0, ..., Slice(1, 3)).newshape(shape) (7, 2)
See also
- property raw¶
Return the equivalent of
selfthat can be used as an indexNumPy does not allow custom objects to be used as indices, with the exception of integer indices, so to use an ndindex object as an index, it is necessary to use
raw.>>> from ndindex import Slice >>> import numpy as np >>> a = np.arange(5) >>> s = Slice(2, 4) >>> a[s] Traceback (most recent call last): ... IndexError: only integers, slices (`:`), ellipsis (`...`), numpy.newaxis (`None`) and integer or boolean arrays are valid indices >>> a[s.raw] array([2, 3])
- reduce(shape=None, *, axis=0, negative_int=False)[source]¶
Reduce a
BooleanArrayindex on an array of shapeshape.The result will either be
IndexErrorif the index is invalid for the given shape, or aBooleanArrayindex. Presently, no simplifications are done for BooleanArray: ifreduce()does not produce anIndexArraythe index returned will be the same asself.>>> from ndindex import BooleanArray >>> idx = BooleanArray([True, False]) >>> idx.reduce((3,)) Traceback (most recent call last): ... IndexError: boolean index did not match indexed array along axis 0; size of axis is 3 but size of corresponding boolean axis is 2 >>> idx.reduce((2,)) BooleanArray([True, False])
- selected_indices(shape, axis=0)[source]¶
Return an iterator over all indices that are selected by
selfon an array of shapeshape.The result is a set of indices
isuch that[a[i] for i in idx.selected_indices(a.shape)]is all the elements ofa[idx]. The indices are all iterated over in C (i.e., row major) order.>>> from ndindex import Slice, Tuple >>> idx = Slice(5, 10) >>> list(idx.selected_indices(20)) [Integer(5), Integer(6), Integer(7), Integer(8), Integer(9)] >>> idx = Tuple(Slice(5, 10), Slice(0, 2)) >>> list(idx.selected_indices((20, 3))) [Tuple(5, 0), Tuple(5, 1), Tuple(6, 0), Tuple(6, 1), Tuple(7, 0), Tuple(7, 1), Tuple(8, 0), Tuple(8, 1), Tuple(9, 0), Tuple(9, 1)]
To correspond these indices to the elements of
a[idx], you can useiter_indices(idx.newshape(shape)), since both iterators iterate the indices in C order.>>> from ndindex import iter_indices >>> idx = Tuple(Slice(3, 5), Slice(0, 2)) >>> shape = (5, 5) >>> import numpy as np >>> a = np.arange(25).reshape(shape) >>> for a_idx, (new_idx,) in zip( ... idx.selected_indices(shape), ... iter_indices(idx.newshape(shape))): ... print(a_idx, new_idx, a[a_idx.raw], a[idx.raw][new_idx.raw]) Tuple(3, 0) Tuple(0, 0) 15 15 Tuple(3, 1) Tuple(0, 1) 16 16 Tuple(4, 0) Tuple(1, 0) 20 20 Tuple(4, 1) Tuple(1, 1) 21 21
See also
ndindex.iter_indicesAn iterator of indices to select every element for arrays of a given shape.
ndindex.ChunkSize.as_subchunksA high-level iterator that efficiently gives only those chunks that intersect with a given index
- property shape¶
Return the shape of the array of self.
This is the same as
self.array.shape. Note that this is not the same as the shape of an array that is indexed byself. Usenewshape()to get that.>>> from ndindex import IntegerArray, BooleanArray >>> IntegerArray([[0], [1]]).shape (2, 1) >>> BooleanArray([[False], [True]]).shape (2, 1)
- property size¶
Return the number of elements of the array of self.
This is the same as
self.array.size. Note that this is not the same as the number of elements of an array that is indexed byself. Usenp.prodonnewshape()to get that.>>> from ndindex import IntegerArray, BooleanArray >>> IntegerArray([[0], [1]]).size 2 >>> BooleanArray([[False], [True]]).size 2