You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: spec/API_specification/indexing.md
+17-5Lines changed: 17 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -17,28 +17,29 @@ To index a single array axis, an array must support standard Python indexing rul
17
17
-**Valid** nonnegative indices must reside on the half-open interval `[0, n)`.
18
18
19
19
```{note}
20
-
21
20
This specification does not require bounds checking. The behavior for out-of-bounds integer indices is left unspecified.
22
21
```
23
22
24
23
- Negative indices must count backward from the last array index, starting from `-1` (i.e., negative-one-based indexing, where `-1` refers to the last array index).
25
24
26
25
```{note}
27
-
28
26
A negative index `j` is equivalent to `n-j`; the former is syntactic sugar for the latter, providing a shorthand for indexing elements that would otherwise need to be specified in terms of the axis (dimension) size.
29
27
```
30
28
31
29
- **Valid** negative indices must reside on the closed interval `[-n, -1]`.
32
30
33
31
```{note}
34
-
35
32
This specification does not require bounds checking. The behavior for out-of-bounds integer indices is left unspecified.
36
33
```
37
34
38
35
- A negative index `j` is related to a zero-based nonnegative index `i` via `i = n+j`.
39
36
40
37
- Colons `:` must be used for [slices](https://docs.python.org/3/library/functions.html#slice): `start:stop:step`, where `start` is inclusive and `stop` is exclusive.
41
38
39
+
```{note}
40
+
The specification does not support returning scalar (i.e., non-array) values from operations, including indexing. In contrast to standard Python indexing rules, for any index, or combination of indices, which select a single value, the result must be a zero-dimensional array containing the selected value.
41
+
```
42
+
42
43
### Slice Syntax
43
44
44
45
The basic slice syntax is `i:j:k` where `i` is the starting index, `j` is the stopping index, and `k` is the step (`k != 0`). A slice may contain either one or two colons, with either an integer value or nothing on either side of each colon. The following are valid slices.
@@ -60,7 +61,6 @@ A[i:j:k]
60
61
```
61
62
62
63
```{note}
63
-
64
64
Slice syntax can be equivalently achieved using the Python built-in [`slice()`](https://docs.python.org/3/library/functions.html#slice) API. From the perspective of `A`, the behavior of `A[i:j:k]` and `A[slice(i, j, k)]` is indistinguishable (i.e., both retrieve the same set of items from `__getitem__`).
65
65
```
66
66
@@ -134,7 +134,9 @@ Multi-dimensional arrays must extend the concept of single-axis indexing to mult
134
134
- Each axis may be independently indexed via single-axis indexing by providing a comma-separated sequence ("selection tuple") of single-axis indexing expressions (e.g., `A[:, 2:10, :, 5]`).
135
135
136
136
```{note}
137
-
In Python, `x[(exp1, exp2, ..., expN)]` is equivalent to `x[exp1, exp2, ..., expN]`; the latter is syntactic sugar for the former.
137
+
In Python, `A[(exp1, exp2, ..., expN)]` is equivalent to `A[exp1, exp2, ..., expN]`; the latter is syntactic sugar for the former.
138
+
139
+
Accordingly, if `A` has rank `1`, then `A[(2:10,)]` must be equivalent to `A[2:10]`. If `A` has rank `2`, then `A[(2:10, :)]` must be equivalent to `A[2:10, :]`. And so on and so forth.
138
140
```
139
141
140
142
- Providing a single nonnegative integer `i` as a single-axis index must index the same elements as the slice `i:i+1`.
@@ -143,10 +145,20 @@ Multi-dimensional arrays must extend the concept of single-axis indexing to mult
143
145
144
146
- Providing a single integer as a single-axis index must reduce the number of array dimensions by `1` (i.e., the array rank should decrease by one; if `A` has rank `2`, `rank(A)-1 == rank(A[0, :])`). In particular, a selection tuple with the `m`th element an integer (and all other entries `:`) indexes a sub-array with rank `N-1`.
145
147
148
+
```{note}
149
+
When providing a single integer as a single-axis index to an array of rank `1`, the result should be an array of rank `0`, not a NumPy scalar. Note that this behavior differs from NumPy.
150
+
```
151
+
146
152
- Providing a slice must retain array dimensions (i.e., the array rank must remain the same; `rank(A) == rank(A[:])`).
147
153
148
154
- Providing [ellipsis](https://docs.python.org/3/library/constants.html#Ellipsis) must apply `:` to each dimension necessary to index all dimensions (e.g., if `A` has rank `4`, `A[1:, ..., 2:5] == A[1:, :, :, 2:5]`). Only a single ellipsis must be allowed. An `IndexError` exception must be raised if more than one ellipsis is provided.
149
155
156
+
- Providing an empty tuple or an ellipsis to an array of rank `0` must result in an array of the same rank (i.e., if `A` has rank `0`, `A == A[()]` and `A == A[...]`).
157
+
158
+
```{note}
159
+
This behavior differs from NumPy where providing an empty tuple to an array of rank `0` returns a NumPy scalar.
160
+
```
161
+
150
162
- Except in the case of providing a single ellipsis (e.g., `A[2:10, ...]` or `A[1:, ..., 2:5]`), the number of provided single-axis indexing expressions should equal `N`. For example, if `A` has rank `2`, a single-axis indexing expression should be explicitly provided for both axes (e.g., `A[2:10, :]`). An `IndexError` exception should be raised if the number of provided single-axis indexing expressions is less than `N`.
0 commit comments