Indexing onndarrays#

ndarrays can be indexed using the standard Pythonx[obj] syntax, wherex is the array andobj the selection.There are different kinds of indexing available depending onobj:basic indexing, advanced indexing and field access.

Most of the following examples show the use of indexing whenreferencing data in an array. The examples work just as wellwhen assigning to an array. SeeAssigning values to indexed arrays forspecific examples and explanations on how assignments work.

Note that in Python,x[(exp1,exp2,...,expN)] is equivalent tox[exp1,exp2,...,expN]; the latter is just syntactic sugarfor the former.

Basic indexing#

Single element indexing#

Single element indexing worksexactly like that for other standard Python sequences. It is 0-based,and accepts negative indices for indexing from the end of the array.

>>>x=np.arange(10)>>>x[2]2>>>x[-2]8

It is not necessary toseparate each dimension’s index into its own set of square brackets.

>>>x.shape=(2,5)# now x is 2-dimensional>>>x[1,3]8>>>x[1,-1]9

Note that if one indexes a multidimensional array with fewer indicesthan dimensions, one gets a subdimensional array. For example:

>>>x[0]array([0, 1, 2, 3, 4])

That is, each index specified selects the array corresponding to therest of the dimensions selected. In the above example, choosing 0means that the remaining dimension of length 5 is being left unspecified,and that what is returned is an array of that dimensionality and size.It must be noted that the returned array is aview, i.e., it is not acopy of the original, but points to the same values in memory as does theoriginal array.In this case, the 1-D array at the first position (0) is returned.So using a single index on the returned array, results in a singleelement being returned. That is:

>>>x[0][2]2

So note thatx[0,2]==x[0][2] though the second case is moreinefficient as a new temporary array is created after the first indexthat is subsequently indexed by 2.

Note

NumPy uses C-order indexing. That means that the lastindex usually represents the most rapidly changing memory location,unlike Fortran or IDL, where the first index represents the mostrapidly changing location in memory. This difference represents agreat potential for confusion.

Slicing and striding#

Basic slicing extends Python’s basic concept of slicing to Ndimensions. Basic slicing occurs whenobj is aslice object(constructed bystart:stop:step notation inside of brackets), aninteger, or a tuple of slice objects and integers.Ellipsisandnewaxis objects can be interspersed with these aswell.

The simplest case of indexing withN integers returns anarrayscalar representing the corresponding item. As inPython, all indices are zero-based: for thei-th index\(n_i\),the valid range is\(0 \le n_i < d_i\) where\(d_i\) is thei-th element of the shape of the array. Negative indices areinterpreted as counting from the end of the array (i.e., if\(n_i < 0\), it means\(n_i + d_i\)).

All arrays generated by basic slicing are alwaysviewsof the original array.

Note

NumPy slicing creates aview instead of a copy as in the case ofbuilt-in Python sequences such as string, tuple and list.Care must be taken when extractinga small portion from a large array which becomes useless after theextraction, because the small portion extracted contains a referenceto the large original array whose memory will not be released untilall arrays derived from it are garbage-collected. In such cases anexplicitcopy() is recommended.

The standard rules of sequence slicing apply to basic slicing on aper-dimension basis (including using a step index). Some usefulconcepts to remember include:

  • The basic slice syntax isi:j:k wherei is the starting index,j is the stopping index, andk is the step (\(k\neq0\)).This selects them elements (in the corresponding dimension) withindex valuesi,i + k, …,i + (m - 1) k where\(m = q + (r\neq0)\) andq andr are the quotient and remainderobtained by dividingj - i byk:j - i = q k + r, so thati + (m - 1) k < j.For example:

    >>>x=np.array([0,1,2,3,4,5,6,7,8,9])>>>x[1:7:2]array([1, 3, 5])
  • Negativei andj are interpreted asn + i andn + j wheren is the number of elements in the corresponding dimension.Negativek makes stepping go towards smaller indices.From the above example:

    >>>x[-2:10]array([8, 9])>>>x[-3:3:-1]array([7, 6, 5, 4])
  • Assumen is the number of elements in the dimension beingsliced. Then, ifi is not given it defaults to 0 fork > 0 andn - 1 fork < 0 . Ifj is not given it defaults ton fork > 0and-n-1 fork < 0 . Ifk is not given it defaults to 1. Note that:: is the same as: and means select all indices along thisaxis.From the above example:

    >>>x[5:]array([5, 6, 7, 8, 9])
  • If the number of objects in the selection tuple is less thanN, then: is assumed for any subsequent dimensions.For example:

    >>>x=np.array([[[1],[2],[3]],[[4],[5],[6]]])>>>x.shape(2, 3, 1)>>>x[1:2]array([[[4],        [5],        [6]]])
  • An integer,i, returns the same values asi:i+1except the dimensionality of the returned object is reduced by1. In particular, a selection tuple with thep-thelement an integer (and all other entries:) returns thecorresponding sub-array with dimensionN - 1. IfN = 1then the returned object is an array scalar. These objects areexplained inScalars.

  • If the selection tuple has all entries: except thep-th entry which is a slice objecti:j:k,then the returned array has dimensionN formed bystacking, along thep-th axis, the sub-arrays returned by integerindexing of elementsi,i+k, …,i + (m - 1) k < j.

  • Basic slicing with more than one non-: entry in the slicingtuple, acts like repeated application of slicing using a singlenon-: entry, where the non-: entries are successively taken(with all other non-: entries replaced by:). Thus,x[ind1,...,ind2,:] acts likex[ind1][...,ind2,:] under basicslicing.

    Warning

    The above isnot true for advanced indexing.

  • You may use slicing to set values in the array, but (unlike lists) youcan never grow the array. The size of the value to be set inx[obj]=value must be (broadcastable to) the same shape asx[obj].

  • A slicing tuple can always be constructed asobjand used in thex[obj] notation. Slice objects can be used inthe construction in place of the[start:stop:step]notation. For example,x[1:10:5,::-1] can also be implementedasobj=(slice(1,10,5),slice(None,None,-1));x[obj] . Thiscan be useful for constructing generic code that works on arraysof arbitrary dimensions. SeeDealing with variable numbers of indices within programsfor more information.

Dimensional indexing tools#

There are some tools to facilitate the easy matching of array shapes withexpressions and in assignments.

Ellipsis expands to the number of: objects needed for theselection tuple to index all dimensions. In most cases, this means that thelength of the expanded selection tuple isx.ndim. There may only be asingle ellipsis present.From the above example:

>>>x[...,0]array([[1, 2, 3],      [4, 5, 6]])

This is equivalent to:

>>>x[:,:,0]array([[1, 2, 3],      [4, 5, 6]])

Eachnewaxis object in the selection tuple serves to expandthe dimensions of the resulting selection by one unit-lengthdimension. The added dimension is the position of thenewaxisobject in the selection tuple.newaxis is an alias forNone, andNone can be used in place of this with the same result.From the above example:

>>>x[:,np.newaxis,:,:].shape(2, 1, 3, 1)>>>x[:,None,:,:].shape(2, 1, 3, 1)

This can be handy to combine twoarrays in a way that otherwise would require explicit reshapingoperations. For example:

>>>x=np.arange(5)>>>x[:,np.newaxis]+x[np.newaxis,:]array([[0, 1, 2, 3, 4],      [1, 2, 3, 4, 5],      [2, 3, 4, 5, 6],      [3, 4, 5, 6, 7],      [4, 5, 6, 7, 8]])

Advanced indexing#

Advanced indexing is triggered when the selection object,obj, is anon-tuple sequence object, anndarray (of data type integer or bool),or a tuple with at least one sequence object or ndarray (of data typeinteger or bool). There are two types of advanced indexing: integerand Boolean.

Advanced indexing always returns acopy of the data (contrast withbasic slicing that returns aview).

Warning

The definition of advanced indexing means thatx[(1,2,3),] isfundamentally different thanx[(1,2,3)]. The latter isequivalent tox[1,2,3] which will trigger basic selection whilethe former will trigger advanced indexing. Be sure to understandwhy this occurs.

Integer array indexing#

Integer array indexing allows selection of arbitrary items in the arraybased on theirN-dimensional index. Each integer array represents a numberof indices into that dimension.

Negative values are permitted in the index arrays and work as they do withsingle indices or slices:

>>>x=np.arange(10,1,-1)>>>xarray([10,  9,  8,  7,  6,  5,  4,  3,  2])>>>x[np.array([3,3,1,8])]array([7, 7, 9, 2])>>>x[np.array([3,3,-3,8])]array([7, 7, 4, 2])

If the index values are out of bounds then anIndexError is thrown:

>>>x=np.array([[1,2],[3,4],[5,6]])>>>x[np.array([1,-1])]array([[3, 4],      [5, 6]])>>>x[np.array([3,4])]Traceback (most recent call last):...IndexError:index 3 is out of bounds for axis 0 with size 3

When the index consists of as many integer arrays as dimensions of the arraybeing indexed, the indexing is straightforward, but different from slicing.

Advanced indices always arebroadcast anditerated asone:

result[i_1,...,i_M]==x[ind_1[i_1,...,i_M],ind_2[i_1,...,i_M],...,ind_N[i_1,...,i_M]]

Note that the resulting shape is identical to the (broadcast) indexing arrayshapesind_1,...,ind_N. If the indices cannot be broadcast to thesame shape, an exceptionIndexError:shapemismatch:indexingarrayscouldnotbebroadcasttogetherwithshapes... is raised.

Indexing with multidimensional index arrays tendto be more unusual uses, but they are permitted, and they are useful for someproblems. We’ll start with the simplest multidimensional case:

>>>y=np.arange(35).reshape(5,7)>>>yarray([[ 0,  1,  2,  3,  4,  5,  6],       [ 7,  8,  9, 10, 11, 12, 13],       [14, 15, 16, 17, 18, 19, 20],       [21, 22, 23, 24, 25, 26, 27],       [28, 29, 30, 31, 32, 33, 34]])>>>y[np.array([0,2,4]),np.array([0,1,2])]array([ 0, 15, 30])

In this case, if the index arrays have a matching shape, and there is anindex array for each dimension of the array being indexed, the resultantarray has the same shape as the index arrays, and the values correspondto the index set for each position in the index arrays. In this example,the first index value is 0 for both index arrays, and thus the first valueof the resultant array isy[0,0]. The next value isy[2,1], andthe last isy[4,2].

If the index arrays do not have the same shape, there is an attempt tobroadcast them to the same shape. If they cannot be broadcast to the sameshape, an exception is raised:

>>>y[np.array([0,2,4]),np.array([0,1])]Traceback (most recent call last):...IndexError:shape mismatch: indexing arrays could not be broadcasttogether with shapes (3,) (2,)

The broadcasting mechanism permits index arrays to be combined withscalars for other indices. The effect is that the scalar value is usedfor all the corresponding values of the index arrays:

>>>y[np.array([0,2,4]),1]array([ 1, 15, 29])

Jumping to the next level of complexity, it is possible to only partiallyindex an array with index arrays. It takes a bit of thought to understandwhat happens in such cases. For example if we just use one index arraywith y:

>>>y[np.array([0,2,4])]array([[ 0,  1,  2,  3,  4,  5,  6],       [14, 15, 16, 17, 18, 19, 20],       [28, 29, 30, 31, 32, 33, 34]])

It results in the construction of a new array where each value of theindex array selects one row from the array being indexed and the resultantarray has the resulting shape (number of index elements, size of row).

In general, the shape of the resultant array will be the concatenation ofthe shape of the index array (or the shape that all the index arrays werebroadcast to) with the shape of any unused dimensions (those not indexed)in the array being indexed.

Example

From each row, a specific element should be selected. The row index is just[0,1,2] and the column index specifies the element to choose for thecorresponding row, here[0,1,0]. Using both together the taskcan be solved using advanced indexing:

>>>x=np.array([[1,2],[3,4],[5,6]])>>>x[[0,1,2],[0,1,0]]array([1, 4, 5])

To achieve a behaviour similar to the basic slicing above, broadcasting can beused. The functionix_ can help with this broadcasting. This is bestunderstood with an example.

Example

From a 4x3 array the corner elements should be selected using advancedindexing. Thus all elements for which the column is one of[0,2] andthe row is one of[0,3] need to be selected. To use advanced indexingone needs to select all elementsexplicitly. Using the method explainedpreviously one could write:

>>>x=np.array([[0,1,2],...[3,4,5],...[6,7,8],...[9,10,11]])>>>rows=np.array([[0,0],...[3,3]],dtype=np.intp)>>>columns=np.array([[0,2],...[0,2]],dtype=np.intp)>>>x[rows,columns]array([[ 0,  2],       [ 9, 11]])

However, since the indexing arrays above just repeat themselves,broadcasting can be used (compare operations such asrows[:,np.newaxis]+columns) to simplify this:

>>>rows=np.array([0,3],dtype=np.intp)>>>columns=np.array([0,2],dtype=np.intp)>>>rows[:,np.newaxis]array([[0],       [3]])>>>x[rows[:,np.newaxis],columns]array([[ 0,  2],       [ 9, 11]])

This broadcasting can also be achieved using the functionix_:

>>>x[np.ix_(rows,columns)]array([[ 0,  2],       [ 9, 11]])

Note that without thenp.ix_ call, only the diagonal elements wouldbe selected:

>>>x[rows,columns]array([ 0, 11])

This difference is the most important thing to remember aboutindexing with multiple advanced indices.

Example

A real-life example of where advanced indexing may be useful is for a colorlookup table where we want to map the values of an image into RGB triples fordisplay. The lookup table could have a shape (nlookup, 3). Indexingsuch an array with an image with shape (ny, nx) with dtype=np.uint8(or any integer type so long as values are with the bounds of thelookup table) will result in an array of shape (ny, nx, 3) where atriple of RGB values is associated with each pixel location.

Boolean array indexing#

This advanced indexing occurs whenobj is an array object of Booleantype, such as may be returned from comparison operators. A singleboolean index array is practically identical tox[obj.nonzero()] where,as described above,obj.nonzero() returns atuple (of lengthobj.ndim) of integer indexarrays showing theTrue elements ofobj. However, it isfaster whenobj.shape==x.shape.

Ifobj.ndim==x.ndim,x[obj]returns a 1-dimensional array filled with the elements ofxcorresponding to theTrue values ofobj. The search orderwill berow-major, C-style. An index error will be raised ifthe shape ofobj does not match the corresponding dimensions ofx,regardless of whether those values areTrue orFalse.

A common use case for this is filtering for desired element values.For example, one may wish to select all entries from an array whichare notnumpy.nan:

>>>x=np.array([[1.,2.],[np.nan,3.],[np.nan,np.nan]])>>>x[~np.isnan(x)]array([1., 2., 3.])

Or wish to add a constant to all negative elements:

>>>x=np.array([1.,-1.,-2.,3])>>>x[x<0]+=20>>>xarray([ 1., 19., 18., 3.])

In general if an index includes a Boolean array, the result will beidentical to insertingobj.nonzero() into the same positionand using the integer array indexing mechanism described above.x[ind_1,boolean_array,ind_2] is equivalent tox[(ind_1,)+boolean_array.nonzero()+(ind_2,)].

If there is only one Boolean array and no integer indexing array present,this is straightforward. Care must only be taken to make sure that theboolean index hasexactly as many dimensions as it is supposed to workwith.

In general, when the boolean array has fewer dimensions than the array beingindexed, this is equivalent tox[b,...], which means x is indexed by bfollowed by as many: as are needed to fill out the rank of x. Thus theshape of the result is one dimension containing the number of True elements ofthe boolean array, followed by the remaining dimensions of the array beingindexed:

>>>x=np.arange(35).reshape(5,7)>>>b=x>20>>>b[:,5]array([False, False, False,  True,  True])>>>x[b[:,5]]array([[21, 22, 23, 24, 25, 26, 27],      [28, 29, 30, 31, 32, 33, 34]])

Here the 4th and 5th rows are selected from the indexed array andcombined to make a 2-D array.

Example

From an array, select all rows which sum up to less or equal two:

>>>x=np.array([[0,1],[1,1],[2,2]])>>>rowsum=x.sum(-1)>>>x[rowsum<=2,:]array([[0, 1],       [1, 1]])

Combining multiple Boolean indexing arrays or a Boolean with an integerindexing array can best be understood with theobj.nonzero() analogy. The functionix_also supports boolean arrays and will work without any surprises.

Example

Use boolean indexing to select all rows adding up to an evennumber. At the same time columns 0 and 2 should be selected with anadvanced integer index. Using theix_ function this can be donewith:

>>>x=np.array([[0,1,2],...[3,4,5],...[6,7,8],...[9,10,11]])>>>rows=(x.sum(-1)%2)==0>>>rowsarray([False,  True, False,  True])>>>columns=[0,2]>>>x[np.ix_(rows,columns)]array([[ 3,  5],       [ 9, 11]])

Without thenp.ix_ call, only the diagonal elements would beselected.

Or withoutnp.ix_ (compare the integer array examples):

>>>rows=rows.nonzero()[0]>>>x[rows[:,np.newaxis],columns]array([[ 3,  5],       [ 9, 11]])

Example

Use a 2-D boolean array of shape (2, 3)with four True elements to select rows from a 3-D array of shape(2, 3, 5) results in a 2-D result of shape (4, 5):

>>>x=np.arange(30).reshape(2,3,5)>>>xarray([[[ 0,  1,  2,  3,  4],        [ 5,  6,  7,  8,  9],        [10, 11, 12, 13, 14]],      [[15, 16, 17, 18, 19],        [20, 21, 22, 23, 24],        [25, 26, 27, 28, 29]]])>>>b=np.array([[True,True,False],[False,True,True]])>>>x[b]array([[ 0,  1,  2,  3,  4],      [ 5,  6,  7,  8,  9],      [20, 21, 22, 23, 24],      [25, 26, 27, 28, 29]])

Combining advanced and basic indexing#

When there is at least one slice (:), ellipsis (...) ornewaxisin the index (or the array has more dimensions than there are advanced indices),then the behaviour can be more complicated. It is like concatenating theindexing result for each advanced index element.

In the simplest case, there is only asingle advanced index combined witha slice. For example:

>>>y=np.arange(35).reshape(5,7)>>>y[np.array([0,2,4]),1:3]array([[ 1,  2],       [15, 16],       [29, 30]])

In effect, the slice and index array operation are independent. The sliceoperation extracts columns with index 1 and 2, (i.e. the 2nd and 3rd columns),followed by the index array operation which extracts rows with index 0, 2 and 4(i.e the first, third and fifth rows). This is equivalent to:

>>>y[:,1:3][np.array([0,2,4]),:]array([[ 1,  2],       [15, 16],       [29, 30]])

A single advanced index can, for example, replace a slice and the result arraywill be the same. However, it is a copy and may have a different memory layout.A slice is preferable when it is possible.For example:

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

The easiest way to understand a combination ofmultiple advanced indices maybe to think in terms of the resulting shape. There are two parts to the indexingoperation, the subspace defined by the basic indexing (excluding integers) andthe subspace from the advanced indexing part. Two cases of index combinationneed to be distinguished:

  • The advanced indices are separated by a slice,Ellipsis ornewaxis. For examplex[arr1,:,arr2].

  • The advanced indices are all next to each other.For examplex[...,arr1,arr2,:] butnotx[arr1,:,1]since1 is an advanced index in this regard.

In the first case, the dimensions resulting from the advanced indexingoperation come first in the result array, and the subspace dimensions afterthat.In the second case, the dimensions from the advanced indexing operationsare inserted into the result array at the same spot as they were in theinitial array (the latter logic is what makes simple advanced indexingbehave just like slicing).

Example

Supposex.shape is (10, 20, 30) andind is a (2, 5, 2)-shapedindexingintp array, thenresult=x[...,ind,:] hasshape (10, 2, 5, 2, 30) because the (20,)-shaped subspace has beenreplaced with a (2, 5, 2)-shaped broadcasted indexing subspace. Ifwe leti, j, k loop over the (2, 5, 2)-shaped subspace thenresult[...,i,j,k,:]=x[...,ind[i,j,k],:]. This exampleproduces the same result asx.take(ind,axis=-2).

Example

Letx.shape be (10, 20, 30, 40, 50) and supposeind_1andind_2 can be broadcast to the shape (2, 3, 4). Thenx[:,ind_1,ind_2] has shape (10, 2, 3, 4, 40, 50) because the(20, 30)-shaped subspace from X has been replaced with the(2, 3, 4) subspace from the indices. However,x[:,ind_1,:,ind_2] has shape (2, 3, 4, 10, 30, 50) because thereis no unambiguous place to drop in the indexing subspace, thusit is tacked-on to the beginning. It is always possible to use.transpose() to move the subspaceanywhere desired. Note that this example cannot be replicatedusingtake.

Example

Slicing can be combined with broadcasted boolean indices:

>>>x=np.arange(35).reshape(5,7)>>>b=x>20>>>barray([[False, False, False, False, False, False, False],      [False, False, False, False, False, False, False],      [False, False, False, False, False, False, False],      [ True,  True,  True,  True,  True,  True,  True],      [ True,  True,  True,  True,  True,  True,  True]])>>>x[b[:,5],1:3]array([[22, 23],      [29, 30]])

Field access#

If thendarray object is a structured array thefieldsof the array can be accessed by indexing the array with strings,dictionary-like.

Indexingx['field-name'] returns a newview to the array,which is of the same shape asx (except when the field is asub-array) but of data typex.dtype['field-name'] and containsonly the part of the data in the specified field. Also,record array scalars can be “indexed” this way.

Indexing into a structured array can also be done with a list of field names,e.g.x[['field-name1','field-name2']]. As of NumPy 1.16, this returns aview containing only those fields. In older versions of NumPy, it returned acopy. See the user guide section onStructured arrays for moreinformation on multifield indexing.

If the accessed field is a sub-array, the dimensions of the sub-arrayare appended to the shape of the result.For example:

>>>x=np.zeros((2,2),dtype=[('a',np.int32),('b',np.float64,(3,3))])>>>x['a'].shape(2, 2)>>>x['a'].dtypedtype('int32')>>>x['b'].shape(2, 2, 3, 3)>>>x['b'].dtypedtype('float64')

Flat iterator indexing#

x.flat returns an iterator that will iterateover the entire array (in C-contiguous style with the last indexvarying the fastest). This iterator object can also be indexed usingbasic slicing or advanced indexing as long as the selection object isnot a tuple. This should be clear from the fact thatx.flat is a 1-dimensional view. It can be used for integerindexing with 1-dimensional C-style-flat indices. The shape of anyreturned array is therefore the shape of the integer indexing object.

Assigning values to indexed arrays#

As mentioned, one can select a subset of an array to assign to usinga single index, slices, and index and mask arrays. The value beingassigned to the indexed array must be shape consistent (the same shapeor broadcastable to the shape the index produces). For example, it ispermitted to assign a constant to a slice:

>>>x=np.arange(10)>>>x[2:7]=1

or an array of the right size:

>>>x[2:7]=np.arange(5)

Note that assignments may result in changes if assigninghigher types to lower types (like floats to ints) or evenexceptions (assigning complex to floats or ints):

>>>x[1]=1.2>>>x[1]1>>>x[1]=1.2jTraceback (most recent call last):...TypeError:can't convert complex to int

Unlike some of the references (such as array and mask indices)assignments are always made to the original data in the array(indeed, nothing else would make sense!). Note though, that someactions may not work as one may naively expect. This particularexample is often surprising to people:

>>>x=np.arange(0,50,10)>>>xarray([ 0, 10, 20, 30, 40])>>>x[np.array([1,1,3,1])]+=1>>>xarray([ 0, 11, 20, 31, 40])

Where people expect that the 1st location will be incremented by 3.In fact, it will only be incremented by 1. The reason is thata new array is extracted from the original (as a temporary) containingthe values at 1, 1, 3, 1, then the value 1 is added to the temporary,and then the temporary is assigned back to the original array. Thusthe value of the array atx[1]+1 is assigned tox[1] three times,rather than being incremented 3 times.

Dealing with variable numbers of indices within programs#

The indexing syntax is very powerful but limiting when dealing witha variable number of indices. For example, if you want to writea function that can handle arguments with various numbers ofdimensions without having to write special case code for eachnumber of possible dimensions, how can that be done? If onesupplies to the index a tuple, the tuple will be interpretedas a list of indices. For example:

>>>z=np.arange(81).reshape(3,3,3,3)>>>indices=(1,1,1,1)>>>z[indices]40

So one can use code to construct tuples of any number of indicesand then use these within an index.

Slices can be specified within programs by using the slice() functionin Python. For example:

>>>indices=(1,1,1,slice(0,2))# same as [1, 1, 1, 0:2]>>>z[indices]array([39, 40])

Likewise, ellipsis can be specified by code by using the Ellipsisobject:

>>>indices=(1,Ellipsis,1)# same as [1, ..., 1]>>>z[indices]array([[28, 31, 34],       [37, 40, 43],       [46, 49, 52]])

For this reason, it is possible to use the output from thenp.nonzero() function directly as an index sinceit always returns a tuple of index arrays.

Because of the special treatment of tuples, they are not automaticallyconverted to an array as a list would be. As an example:

>>>z[[1,1,1,1]]# produces a large arrayarray([[[[27, 28, 29],         [30, 31, 32], ...>>>z[(1,1,1,1)]# returns a single value40

Detailed notes#

These are some detailed notes, which are not of importance for day to dayindexing (in no particular order):

  • The native NumPy indexing type isintp and may differ from thedefault integer array type.intp is the smallest data typesufficient to safely index any array; for advanced indexing it may befaster than other types.

  • For advanced assignments, there is in general no guarantee for theiteration order. This means that if an element is set more than once,it is not possible to predict the final result.

  • An empty (tuple) index is a full scalar index into a zero-dimensional array.x[()] returns ascalar ifx is zero-dimensional and a viewotherwise. On the other hand,x[...] always returns a view.

  • If a zero-dimensional array is present in the indexand it is a fullinteger index the result will be ascalar and not a zero-dimensional array.(Advanced indexing is not triggered.)

  • When an ellipsis (...) is present but has no size (i.e. replaces zero:) the result will still always be an array. A view if no advanced indexis present, otherwise a copy.

  • Thenonzero equivalence for Boolean arrays does not hold for zerodimensional boolean arrays.

  • When the result of an advanced indexing operation has no elements but anindividual index is out of bounds, whether or not anIndexError israised is undefined (e.g.x[[],[123]] with123 being out of bounds).

  • When acasting error occurs during assignment (for example updating anumerical array using a sequence of strings), the array being assignedto may end up in an unpredictable partially updated state.However, if any other error (such as an out of bounds index) occurs, thearray will remain unchanged.

  • The memory layout of an advanced indexing result is optimized for eachindexing operation and no particular memory order can be assumed.

  • When using a subclass (especially one which manipulates its shape), thedefaultndarray.__setitem__ behaviour will call__getitem__ forbasic indexing but not foradvanced indexing. For such a subclass it maybe preferable to callndarray.__setitem__ with abase class ndarrayview on the data. Thismust be done if the subclasses__getitem__ doesnot return views.