IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
5.4 Index Arrays


5.4 Index Arrays

Arrays used as subscripts have special meanings which implicitly invoke the functions put (page ), take (page ), or compress (page ). If the array is of Bool type, then the indexing will be treated as the equivalent of the compress function. If the array is of an integer type, then a take or put operation is implied. We will generalize the existing take and put as follows: If ind1, ind2, ... indN are index arrays (arrays of integers whose values indicate the index into another array), then x[ind1, ind2] forms a new array with the same shape as ind1, ind2 (they all must be broadcastable to the same shape) and values such: "result[i,j,k] = x[ind1[i,j,k], ind2[i,j,k]]" In this example, ind1, ind2 are index arrays with 3 dimensions (but they could have an arbitrary number of dimensions). To illustrate with some specific examples:

>>> x=2*arange(10)
>>> ind1=[0,4,3,7]
>>> x[ind1]
array([ 0,  8,  6, 14])
>>> ind1=[[0,4],[3,7]]
>>> x[ind1]
array([[ 0,  8],
       [ 6, 14]])
This shows that the same elements in the same order are extracted from x by both forms of ind1, but the result shares the shape of ind1 Something similar happens in two dimensions:
>>> x=reshape(arange(12),(3,4))
>>> x
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>> ind1=array([2,1])
>>> ind2=array([0,3])
>>> x[ind1,ind2]
array([8, 7])
Notice this pulls out x[2,0] and x[1,3] as a one-dimensional array.
>>> ind1=array([[2,2],[1,0]])
>>> ind2=array([[0,1],[3,2]])
>>> x[ind1,ind2]
array([[8, 9],
       [7, 2]])
This pulls out x[2,0], x[2,1], x[1,3], and x[0,2], reading the ind1 and ind2 arrays left to right, and then reshapes the result to the same (2,2) shape as ind1 and ind2 have.
>>> ind1.shape=(4,)
>>> ind2.shape=(4,)
>>> x[ind1,ind2]
array([8, 9, 7, 2])

Notice this is the same values in the same order, but now as a one-d array. One index array does a broadcast:

>>> x[ind1]
array([[ 8,  9, 10, 11],
       [ 8,  9, 10, 11],
       [ 4,  5,  6,  7],
       [ 0,  1,  2,  3]])
>>> ind1.shape=(2,2)
>>> x[ind1]
array([[[ 8,  9, 10, 11],
        [ 8,  9, 10, 11]],

       [[ 4,  5,  6,  7],
        [ 0,  1,  2,  3]]])

Again, note that the same 'elements', in this case rows of x, are returned in both cases. But in the second case, ind1 had two dimensions, and so using it to index only one dimension of a two-d array results in a three-d output of shape (2,2,4); i.e., a 2 by 2 'array' of 4-element rows.

When using constants for some of the index positions, then the result uses that constant for all values. Slices and strides (at least initially) will not be permitted in the same subscript as index arrays. So

>>> x[ind1, 2]
array([[10, 10],
  [ 6,  2]])
would be legal, but
>>> x[ind1, 1:3]
Traceback (most recent call last):
...
IndexError: Cannot mix arrays and slices as indices
would not be. Similarly for assignment:
x[ind1, ind2, ind3] = values
will form a new array such that:
x[ind1[i,j,k], ind2[i,j,k], ind3[i,j,k]] = values[i,j,k]

The index arrays and the value array must be broadcast consistently. (As an example: ind1.setshape((5,4)), ind2.setshape((5,)), ind3.setshape((1,4)), and values.setshape((1,)).)

>>> x=zeros((10,10))
>>> x[[2,5,6],array([0,1,9,3])[:,NewAxis]]=array([1,2,3,4])[:,NewAxis]
>>> x
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 2, 0, 4, 0, 0, 0, 0, 0, 3],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 2, 0, 4, 0, 0, 0, 0, 0, 3],
       [1, 2, 0, 4, 0, 0, 0, 0, 0, 3],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]])
If indices are repeated, the last value encountered will be stored. When an index is too large, Numarray raises an IndexError exception. When an index is negative, Numarray will interpret it in the usual Python style, counting backwards from the end. Use of the equivalent take and put functions will allow other interpretations of the indices (clip out of bounds indices, allow negative indices to work backwards as they do when used individually, or for indices to wrap around). The same behavior applies for functions such as choose and where.

Send comments to the NumArray community.