annotate DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/doc/indexing.py @ 118:770eb830ec19 emscripten

Typo fix
author Chris Cannam
date Wed, 18 May 2016 16:14:08 +0100
parents 2a2c65a20a8b
children
rev   line source
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