Chris@87
|
1 """
|
Chris@87
|
2 ==============
|
Chris@87
|
3 Array indexing
|
Chris@87
|
4 ==============
|
Chris@87
|
5
|
Chris@87
|
6 Array indexing refers to any use of the square brackets ([]) to index
|
Chris@87
|
7 array values. There are many options to indexing, which give numpy
|
Chris@87
|
8 indexing great power, but with power comes some complexity and the
|
Chris@87
|
9 potential for confusion. This section is just an overview of the
|
Chris@87
|
10 various options and issues related to indexing. Aside from single
|
Chris@87
|
11 element indexing, the details on most of these options are to be
|
Chris@87
|
12 found in related sections.
|
Chris@87
|
13
|
Chris@87
|
14 Assignment vs referencing
|
Chris@87
|
15 =========================
|
Chris@87
|
16
|
Chris@87
|
17 Most of the following examples show the use of indexing when
|
Chris@87
|
18 referencing data in an array. The examples work just as well
|
Chris@87
|
19 when assigning to an array. See the section at the end for
|
Chris@87
|
20 specific examples and explanations on how assignments work.
|
Chris@87
|
21
|
Chris@87
|
22 Single element indexing
|
Chris@87
|
23 =======================
|
Chris@87
|
24
|
Chris@87
|
25 Single element indexing for a 1-D array is what one expects. It work
|
Chris@87
|
26 exactly like that for other standard Python sequences. It is 0-based,
|
Chris@87
|
27 and accepts negative indices for indexing from the end of the array. ::
|
Chris@87
|
28
|
Chris@87
|
29 >>> x = np.arange(10)
|
Chris@87
|
30 >>> x[2]
|
Chris@87
|
31 2
|
Chris@87
|
32 >>> x[-2]
|
Chris@87
|
33 8
|
Chris@87
|
34
|
Chris@87
|
35 Unlike lists and tuples, numpy arrays support multidimensional indexing
|
Chris@87
|
36 for multidimensional arrays. That means that it is not necessary to
|
Chris@87
|
37 separate each dimension's index into its own set of square brackets. ::
|
Chris@87
|
38
|
Chris@87
|
39 >>> x.shape = (2,5) # now x is 2-dimensional
|
Chris@87
|
40 >>> x[1,3]
|
Chris@87
|
41 8
|
Chris@87
|
42 >>> x[1,-1]
|
Chris@87
|
43 9
|
Chris@87
|
44
|
Chris@87
|
45 Note that if one indexes a multidimensional array with fewer indices
|
Chris@87
|
46 than dimensions, one gets a subdimensional array. For example: ::
|
Chris@87
|
47
|
Chris@87
|
48 >>> x[0]
|
Chris@87
|
49 array([0, 1, 2, 3, 4])
|
Chris@87
|
50
|
Chris@87
|
51 That is, each index specified selects the array corresponding to the
|
Chris@87
|
52 rest of the dimensions selected. In the above example, choosing 0
|
Chris@87
|
53 means that remaining dimension of lenth 5 is being left unspecified,
|
Chris@87
|
54 and that what is returned is an array of that dimensionality and size.
|
Chris@87
|
55 It must be noted that the returned array is not a copy of the original,
|
Chris@87
|
56 but points to the same values in memory as does the original array.
|
Chris@87
|
57 In this case, the 1-D array at the first position (0) is returned.
|
Chris@87
|
58 So using a single index on the returned array, results in a single
|
Chris@87
|
59 element being returned. That is: ::
|
Chris@87
|
60
|
Chris@87
|
61 >>> x[0][2]
|
Chris@87
|
62 2
|
Chris@87
|
63
|
Chris@87
|
64 So note that ``x[0,2] = x[0][2]`` though the second case is more
|
Chris@87
|
65 inefficient a new temporary array is created after the first index
|
Chris@87
|
66 that is subsequently indexed by 2.
|
Chris@87
|
67
|
Chris@87
|
68 Note to those used to IDL or Fortran memory order as it relates to
|
Chris@87
|
69 indexing. Numpy uses C-order indexing. That means that the last
|
Chris@87
|
70 index usually represents the most rapidly changing memory location,
|
Chris@87
|
71 unlike Fortran or IDL, where the first index represents the most
|
Chris@87
|
72 rapidly changing location in memory. This difference represents a
|
Chris@87
|
73 great potential for confusion.
|
Chris@87
|
74
|
Chris@87
|
75 Other indexing options
|
Chris@87
|
76 ======================
|
Chris@87
|
77
|
Chris@87
|
78 It is possible to slice and stride arrays to extract arrays of the
|
Chris@87
|
79 same number of dimensions, but of different sizes than the original.
|
Chris@87
|
80 The slicing and striding works exactly the same way it does for lists
|
Chris@87
|
81 and tuples except that they can be applied to multiple dimensions as
|
Chris@87
|
82 well. A few examples illustrates best: ::
|
Chris@87
|
83
|
Chris@87
|
84 >>> x = np.arange(10)
|
Chris@87
|
85 >>> x[2:5]
|
Chris@87
|
86 array([2, 3, 4])
|
Chris@87
|
87 >>> x[:-7]
|
Chris@87
|
88 array([0, 1, 2])
|
Chris@87
|
89 >>> x[1:7:2]
|
Chris@87
|
90 array([1, 3, 5])
|
Chris@87
|
91 >>> y = np.arange(35).reshape(5,7)
|
Chris@87
|
92 >>> y[1:5:2,::3]
|
Chris@87
|
93 array([[ 7, 10, 13],
|
Chris@87
|
94 [21, 24, 27]])
|
Chris@87
|
95
|
Chris@87
|
96 Note that slices of arrays do not copy the internal array data but
|
Chris@87
|
97 also produce new views of the original data.
|
Chris@87
|
98
|
Chris@87
|
99 It is possible to index arrays with other arrays for the purposes of
|
Chris@87
|
100 selecting lists of values out of arrays into new arrays. There are
|
Chris@87
|
101 two different ways of accomplishing this. One uses one or more arrays
|
Chris@87
|
102 of index values. The other involves giving a boolean array of the proper
|
Chris@87
|
103 shape to indicate the values to be selected. Index arrays are a very
|
Chris@87
|
104 powerful tool that allow one to avoid looping over individual elements in
|
Chris@87
|
105 arrays and thus greatly improve performance.
|
Chris@87
|
106
|
Chris@87
|
107 It is possible to use special features to effectively increase the
|
Chris@87
|
108 number of dimensions in an array through indexing so the resulting
|
Chris@87
|
109 array aquires the shape needed for use in an expression or with a
|
Chris@87
|
110 specific function.
|
Chris@87
|
111
|
Chris@87
|
112 Index arrays
|
Chris@87
|
113 ============
|
Chris@87
|
114
|
Chris@87
|
115 Numpy arrays may be indexed with other arrays (or any other sequence-
|
Chris@87
|
116 like object that can be converted to an array, such as lists, with the
|
Chris@87
|
117 exception of tuples; see the end of this document for why this is). The
|
Chris@87
|
118 use of index arrays ranges from simple, straightforward cases to
|
Chris@87
|
119 complex, hard-to-understand cases. For all cases of index arrays, what
|
Chris@87
|
120 is returned is a copy of the original data, not a view as one gets for
|
Chris@87
|
121 slices.
|
Chris@87
|
122
|
Chris@87
|
123 Index arrays must be of integer type. Each value in the array indicates
|
Chris@87
|
124 which value in the array to use in place of the index. To illustrate: ::
|
Chris@87
|
125
|
Chris@87
|
126 >>> x = np.arange(10,1,-1)
|
Chris@87
|
127 >>> x
|
Chris@87
|
128 array([10, 9, 8, 7, 6, 5, 4, 3, 2])
|
Chris@87
|
129 >>> x[np.array([3, 3, 1, 8])]
|
Chris@87
|
130 array([7, 7, 9, 2])
|
Chris@87
|
131
|
Chris@87
|
132
|
Chris@87
|
133 The index array consisting of the values 3, 3, 1 and 8 correspondingly
|
Chris@87
|
134 create an array of length 4 (same as the index array) where each index
|
Chris@87
|
135 is replaced by the value the index array has in the array being indexed.
|
Chris@87
|
136
|
Chris@87
|
137 Negative values are permitted and work as they do with single indices
|
Chris@87
|
138 or slices: ::
|
Chris@87
|
139
|
Chris@87
|
140 >>> x[np.array([3,3,-3,8])]
|
Chris@87
|
141 array([7, 7, 4, 2])
|
Chris@87
|
142
|
Chris@87
|
143 It is an error to have index values out of bounds: ::
|
Chris@87
|
144
|
Chris@87
|
145 >>> x[np.array([3, 3, 20, 8])]
|
Chris@87
|
146 <type 'exceptions.IndexError'>: index 20 out of bounds 0<=index<9
|
Chris@87
|
147
|
Chris@87
|
148 Generally speaking, what is returned when index arrays are used is
|
Chris@87
|
149 an array with the same shape as the index array, but with the type
|
Chris@87
|
150 and values of the array being indexed. As an example, we can use a
|
Chris@87
|
151 multidimensional index array instead: ::
|
Chris@87
|
152
|
Chris@87
|
153 >>> x[np.array([[1,1],[2,3]])]
|
Chris@87
|
154 array([[9, 9],
|
Chris@87
|
155 [8, 7]])
|
Chris@87
|
156
|
Chris@87
|
157 Indexing Multi-dimensional arrays
|
Chris@87
|
158 =================================
|
Chris@87
|
159
|
Chris@87
|
160 Things become more complex when multidimensional arrays are indexed,
|
Chris@87
|
161 particularly with multidimensional index arrays. These tend to be
|
Chris@87
|
162 more unusal uses, but theyare permitted, and they are useful for some
|
Chris@87
|
163 problems. We'll start with thesimplest multidimensional case (using
|
Chris@87
|
164 the array y from the previous examples): ::
|
Chris@87
|
165
|
Chris@87
|
166 >>> y[np.array([0,2,4]), np.array([0,1,2])]
|
Chris@87
|
167 array([ 0, 15, 30])
|
Chris@87
|
168
|
Chris@87
|
169 In this case, if the index arrays have a matching shape, and there is
|
Chris@87
|
170 an index array for each dimension of the array being indexed, the
|
Chris@87
|
171 resultant array has the same shape as the index arrays, and the values
|
Chris@87
|
172 correspond to the index set for each position in the index arrays. In
|
Chris@87
|
173 this example, the first index value is 0 for both index arrays, and
|
Chris@87
|
174 thus the first value of the resultant array is y[0,0]. The next value
|
Chris@87
|
175 is y[2,1], and the last is y[4,2].
|
Chris@87
|
176
|
Chris@87
|
177 If the index arrays do not have the same shape, there is an attempt to
|
Chris@87
|
178 broadcast them to the same shape. If they cannot be broadcast to the
|
Chris@87
|
179 same shape, an exception is raised: ::
|
Chris@87
|
180
|
Chris@87
|
181 >>> y[np.array([0,2,4]), np.array([0,1])]
|
Chris@87
|
182 <type 'exceptions.ValueError'>: shape mismatch: objects cannot be
|
Chris@87
|
183 broadcast to a single shape
|
Chris@87
|
184
|
Chris@87
|
185 The broadcasting mechanism permits index arrays to be combined with
|
Chris@87
|
186 scalars for other indices. The effect is that the scalar value is used
|
Chris@87
|
187 for all the corresponding values of the index arrays: ::
|
Chris@87
|
188
|
Chris@87
|
189 >>> y[np.array([0,2,4]), 1]
|
Chris@87
|
190 array([ 1, 15, 29])
|
Chris@87
|
191
|
Chris@87
|
192 Jumping to the next level of complexity, it is possible to only
|
Chris@87
|
193 partially index an array with index arrays. It takes a bit of thought
|
Chris@87
|
194 to understand what happens in such cases. For example if we just use
|
Chris@87
|
195 one index array with y: ::
|
Chris@87
|
196
|
Chris@87
|
197 >>> y[np.array([0,2,4])]
|
Chris@87
|
198 array([[ 0, 1, 2, 3, 4, 5, 6],
|
Chris@87
|
199 [14, 15, 16, 17, 18, 19, 20],
|
Chris@87
|
200 [28, 29, 30, 31, 32, 33, 34]])
|
Chris@87
|
201
|
Chris@87
|
202 What results is the construction of a new array where each value of
|
Chris@87
|
203 the index array selects one row from the array being indexed and the
|
Chris@87
|
204 resultant array has the resulting shape (size of row, number index
|
Chris@87
|
205 elements).
|
Chris@87
|
206
|
Chris@87
|
207 An example of where this may be useful is for a color lookup table
|
Chris@87
|
208 where we want to map the values of an image into RGB triples for
|
Chris@87
|
209 display. The lookup table could have a shape (nlookup, 3). Indexing
|
Chris@87
|
210 such an array with an image with shape (ny, nx) with dtype=np.uint8
|
Chris@87
|
211 (or any integer type so long as values are with the bounds of the
|
Chris@87
|
212 lookup table) will result in an array of shape (ny, nx, 3) where a
|
Chris@87
|
213 triple of RGB values is associated with each pixel location.
|
Chris@87
|
214
|
Chris@87
|
215 In general, the shape of the resulant array will be the concatenation
|
Chris@87
|
216 of the shape of the index array (or the shape that all the index arrays
|
Chris@87
|
217 were broadcast to) with the shape of any unused dimensions (those not
|
Chris@87
|
218 indexed) in the array being indexed.
|
Chris@87
|
219
|
Chris@87
|
220 Boolean or "mask" index arrays
|
Chris@87
|
221 ==============================
|
Chris@87
|
222
|
Chris@87
|
223 Boolean arrays used as indices are treated in a different manner
|
Chris@87
|
224 entirely than index arrays. Boolean arrays must be of the same shape
|
Chris@87
|
225 as the initial dimensions of the array being indexed. In the
|
Chris@87
|
226 most straightforward case, the boolean array has the same shape: ::
|
Chris@87
|
227
|
Chris@87
|
228 >>> b = y>20
|
Chris@87
|
229 >>> y[b]
|
Chris@87
|
230 array([21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34])
|
Chris@87
|
231
|
Chris@87
|
232 The result is a 1-D array containing all the elements in the indexed
|
Chris@87
|
233 array corresponding to all the true elements in the boolean array. As
|
Chris@87
|
234 with index arrays, what is returned is a copy of the data, not a view
|
Chris@87
|
235 as one gets with slices.
|
Chris@87
|
236
|
Chris@87
|
237 The result will be multidimensional if y has more dimensions than b.
|
Chris@87
|
238 For example: ::
|
Chris@87
|
239
|
Chris@87
|
240 >>> b[:,5] # use a 1-D boolean whose first dim agrees with the first dim of y
|
Chris@87
|
241 array([False, False, False, True, True], dtype=bool)
|
Chris@87
|
242 >>> y[b[:,5]]
|
Chris@87
|
243 array([[21, 22, 23, 24, 25, 26, 27],
|
Chris@87
|
244 [28, 29, 30, 31, 32, 33, 34]])
|
Chris@87
|
245
|
Chris@87
|
246 Here the 4th and 5th rows are selected from the indexed array and
|
Chris@87
|
247 combined to make a 2-D array.
|
Chris@87
|
248
|
Chris@87
|
249 In general, when the boolean array has fewer dimensions than the array
|
Chris@87
|
250 being indexed, this is equivalent to y[b, ...], which means
|
Chris@87
|
251 y is indexed by b followed by as many : as are needed to fill
|
Chris@87
|
252 out the rank of y.
|
Chris@87
|
253 Thus the shape of the result is one dimension containing the number
|
Chris@87
|
254 of True elements of the boolean array, followed by the remaining
|
Chris@87
|
255 dimensions of the array being indexed.
|
Chris@87
|
256
|
Chris@87
|
257 For example, using a 2-D boolean array of shape (2,3)
|
Chris@87
|
258 with four True elements to select rows from a 3-D array of shape
|
Chris@87
|
259 (2,3,5) results in a 2-D result of shape (4,5): ::
|
Chris@87
|
260
|
Chris@87
|
261 >>> x = np.arange(30).reshape(2,3,5)
|
Chris@87
|
262 >>> x
|
Chris@87
|
263 array([[[ 0, 1, 2, 3, 4],
|
Chris@87
|
264 [ 5, 6, 7, 8, 9],
|
Chris@87
|
265 [10, 11, 12, 13, 14]],
|
Chris@87
|
266 [[15, 16, 17, 18, 19],
|
Chris@87
|
267 [20, 21, 22, 23, 24],
|
Chris@87
|
268 [25, 26, 27, 28, 29]]])
|
Chris@87
|
269 >>> b = np.array([[True, True, False], [False, True, True]])
|
Chris@87
|
270 >>> x[b]
|
Chris@87
|
271 array([[ 0, 1, 2, 3, 4],
|
Chris@87
|
272 [ 5, 6, 7, 8, 9],
|
Chris@87
|
273 [20, 21, 22, 23, 24],
|
Chris@87
|
274 [25, 26, 27, 28, 29]])
|
Chris@87
|
275
|
Chris@87
|
276 For further details, consult the numpy reference documentation on array indexing.
|
Chris@87
|
277
|
Chris@87
|
278 Combining index arrays with slices
|
Chris@87
|
279 ==================================
|
Chris@87
|
280
|
Chris@87
|
281 Index arrays may be combined with slices. For example: ::
|
Chris@87
|
282
|
Chris@87
|
283 >>> y[np.array([0,2,4]),1:3]
|
Chris@87
|
284 array([[ 1, 2],
|
Chris@87
|
285 [15, 16],
|
Chris@87
|
286 [29, 30]])
|
Chris@87
|
287
|
Chris@87
|
288 In effect, the slice is converted to an index array
|
Chris@87
|
289 np.array([[1,2]]) (shape (1,2)) that is broadcast with the index array
|
Chris@87
|
290 to produce a resultant array of shape (3,2).
|
Chris@87
|
291
|
Chris@87
|
292 Likewise, slicing can be combined with broadcasted boolean indices: ::
|
Chris@87
|
293
|
Chris@87
|
294 >>> y[b[:,5],1:3]
|
Chris@87
|
295 array([[22, 23],
|
Chris@87
|
296 [29, 30]])
|
Chris@87
|
297
|
Chris@87
|
298 Structural indexing tools
|
Chris@87
|
299 =========================
|
Chris@87
|
300
|
Chris@87
|
301 To facilitate easy matching of array shapes with expressions and in
|
Chris@87
|
302 assignments, the np.newaxis object can be used within array indices
|
Chris@87
|
303 to add new dimensions with a size of 1. For example: ::
|
Chris@87
|
304
|
Chris@87
|
305 >>> y.shape
|
Chris@87
|
306 (5, 7)
|
Chris@87
|
307 >>> y[:,np.newaxis,:].shape
|
Chris@87
|
308 (5, 1, 7)
|
Chris@87
|
309
|
Chris@87
|
310 Note that there are no new elements in the array, just that the
|
Chris@87
|
311 dimensionality is increased. This can be handy to combine two
|
Chris@87
|
312 arrays in a way that otherwise would require explicitly reshaping
|
Chris@87
|
313 operations. For example: ::
|
Chris@87
|
314
|
Chris@87
|
315 >>> x = np.arange(5)
|
Chris@87
|
316 >>> x[:,np.newaxis] + x[np.newaxis,:]
|
Chris@87
|
317 array([[0, 1, 2, 3, 4],
|
Chris@87
|
318 [1, 2, 3, 4, 5],
|
Chris@87
|
319 [2, 3, 4, 5, 6],
|
Chris@87
|
320 [3, 4, 5, 6, 7],
|
Chris@87
|
321 [4, 5, 6, 7, 8]])
|
Chris@87
|
322
|
Chris@87
|
323 The ellipsis syntax maybe used to indicate selecting in full any
|
Chris@87
|
324 remaining unspecified dimensions. For example: ::
|
Chris@87
|
325
|
Chris@87
|
326 >>> z = np.arange(81).reshape(3,3,3,3)
|
Chris@87
|
327 >>> z[1,...,2]
|
Chris@87
|
328 array([[29, 32, 35],
|
Chris@87
|
329 [38, 41, 44],
|
Chris@87
|
330 [47, 50, 53]])
|
Chris@87
|
331
|
Chris@87
|
332 This is equivalent to: ::
|
Chris@87
|
333
|
Chris@87
|
334 >>> z[1,:,:,2]
|
Chris@87
|
335 array([[29, 32, 35],
|
Chris@87
|
336 [38, 41, 44],
|
Chris@87
|
337 [47, 50, 53]])
|
Chris@87
|
338
|
Chris@87
|
339 Assigning values to indexed arrays
|
Chris@87
|
340 ==================================
|
Chris@87
|
341
|
Chris@87
|
342 As mentioned, one can select a subset of an array to assign to using
|
Chris@87
|
343 a single index, slices, and index and mask arrays. The value being
|
Chris@87
|
344 assigned to the indexed array must be shape consistent (the same shape
|
Chris@87
|
345 or broadcastable to the shape the index produces). For example, it is
|
Chris@87
|
346 permitted to assign a constant to a slice: ::
|
Chris@87
|
347
|
Chris@87
|
348 >>> x = np.arange(10)
|
Chris@87
|
349 >>> x[2:7] = 1
|
Chris@87
|
350
|
Chris@87
|
351 or an array of the right size: ::
|
Chris@87
|
352
|
Chris@87
|
353 >>> x[2:7] = np.arange(5)
|
Chris@87
|
354
|
Chris@87
|
355 Note that assignments may result in changes if assigning
|
Chris@87
|
356 higher types to lower types (like floats to ints) or even
|
Chris@87
|
357 exceptions (assigning complex to floats or ints): ::
|
Chris@87
|
358
|
Chris@87
|
359 >>> x[1] = 1.2
|
Chris@87
|
360 >>> x[1]
|
Chris@87
|
361 1
|
Chris@87
|
362 >>> x[1] = 1.2j
|
Chris@87
|
363 <type 'exceptions.TypeError'>: can't convert complex to long; use
|
Chris@87
|
364 long(abs(z))
|
Chris@87
|
365
|
Chris@87
|
366
|
Chris@87
|
367 Unlike some of the references (such as array and mask indices)
|
Chris@87
|
368 assignments are always made to the original data in the array
|
Chris@87
|
369 (indeed, nothing else would make sense!). Note though, that some
|
Chris@87
|
370 actions may not work as one may naively expect. This particular
|
Chris@87
|
371 example is often surprising to people: ::
|
Chris@87
|
372
|
Chris@87
|
373 >>> x = np.arange(0, 50, 10)
|
Chris@87
|
374 >>> x
|
Chris@87
|
375 array([ 0, 10, 20, 30, 40])
|
Chris@87
|
376 >>> x[np.array([1, 1, 3, 1])] += 1
|
Chris@87
|
377 >>> x
|
Chris@87
|
378 array([ 0, 11, 20, 31, 40])
|
Chris@87
|
379
|
Chris@87
|
380 Where people expect that the 1st location will be incremented by 3.
|
Chris@87
|
381 In fact, it will only be incremented by 1. The reason is because
|
Chris@87
|
382 a new array is extracted from the original (as a temporary) containing
|
Chris@87
|
383 the values at 1, 1, 3, 1, then the value 1 is added to the temporary,
|
Chris@87
|
384 and then the temporary is assigned back to the original array. Thus
|
Chris@87
|
385 the value of the array at x[1]+1 is assigned to x[1] three times,
|
Chris@87
|
386 rather than being incremented 3 times.
|
Chris@87
|
387
|
Chris@87
|
388 Dealing with variable numbers of indices within programs
|
Chris@87
|
389 ========================================================
|
Chris@87
|
390
|
Chris@87
|
391 The index syntax is very powerful but limiting when dealing with
|
Chris@87
|
392 a variable number of indices. For example, if you want to write
|
Chris@87
|
393 a function that can handle arguments with various numbers of
|
Chris@87
|
394 dimensions without having to write special case code for each
|
Chris@87
|
395 number of possible dimensions, how can that be done? If one
|
Chris@87
|
396 supplies to the index a tuple, the tuple will be interpreted
|
Chris@87
|
397 as a list of indices. For example (using the previous definition
|
Chris@87
|
398 for the array z): ::
|
Chris@87
|
399
|
Chris@87
|
400 >>> indices = (1,1,1,1)
|
Chris@87
|
401 >>> z[indices]
|
Chris@87
|
402 40
|
Chris@87
|
403
|
Chris@87
|
404 So one can use code to construct tuples of any number of indices
|
Chris@87
|
405 and then use these within an index.
|
Chris@87
|
406
|
Chris@87
|
407 Slices can be specified within programs by using the slice() function
|
Chris@87
|
408 in Python. For example: ::
|
Chris@87
|
409
|
Chris@87
|
410 >>> indices = (1,1,1,slice(0,2)) # same as [1,1,1,0:2]
|
Chris@87
|
411 >>> z[indices]
|
Chris@87
|
412 array([39, 40])
|
Chris@87
|
413
|
Chris@87
|
414 Likewise, ellipsis can be specified by code by using the Ellipsis
|
Chris@87
|
415 object: ::
|
Chris@87
|
416
|
Chris@87
|
417 >>> indices = (1, Ellipsis, 1) # same as [1,...,1]
|
Chris@87
|
418 >>> z[indices]
|
Chris@87
|
419 array([[28, 31, 34],
|
Chris@87
|
420 [37, 40, 43],
|
Chris@87
|
421 [46, 49, 52]])
|
Chris@87
|
422
|
Chris@87
|
423 For this reason it is possible to use the output from the np.where()
|
Chris@87
|
424 function directly as an index since it always returns a tuple of index
|
Chris@87
|
425 arrays.
|
Chris@87
|
426
|
Chris@87
|
427 Because the special treatment of tuples, they are not automatically
|
Chris@87
|
428 converted to an array as a list would be. As an example: ::
|
Chris@87
|
429
|
Chris@87
|
430 >>> z[[1,1,1,1]] # produces a large array
|
Chris@87
|
431 array([[[[27, 28, 29],
|
Chris@87
|
432 [30, 31, 32], ...
|
Chris@87
|
433 >>> z[(1,1,1,1)] # returns a single value
|
Chris@87
|
434 40
|
Chris@87
|
435
|
Chris@87
|
436 """
|
Chris@87
|
437 from __future__ import division, absolute_import, print_function
|