Movatterモバイル変換


[0]ホーム

URL:


SciPy

Indexing

ndarrays can be indexed using the standard Pythonx[obj] syntax, wherex is the array andobj the selection.There are three kinds of indexing available: field access, basicslicing, advanced indexing. Which one occurs depends onobj.

Note

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

Basic Slicing and Indexing

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.

Deprecated since version 1.15.0:In order to remain backward compatible with a common usage inNumeric, basic slicing is also initiated if the selection object isany non-ndarray and non-tuple sequence (such as alist) containingslice objects, theEllipsis object, or thenewaxisobject, but not for integer arrays or other embedded sequences.

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

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

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 wherem = 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.

    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.

    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.

    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.

    Example

    >>>x=np.array([[[1],[2],[3]],[[4],[5],[6]]])>>>x.shape(2, 3, 1)>>>x[1:2]array([[[4],        [5],        [6]]])
  • Ellipsis expand to the number of: objects needed tomake a selection tuple of the same length asx.ndim. There mayonly be a single ellipsis present.

    Example

    >>>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.

    Example

    >>>x[:,np.newaxis,:,:].shape(2, 1, 3, 1)
  • 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 byconcatenating the sub-arrays returned by integer indexing ofelementsi,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].

Note

Remember that 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 dimension.

numpy.newaxis

Thenewaxis object can be used in all slicing operations tocreate an axis of length one.newaxis is an alias for‘None’, and ‘None’ can be used in place of this with the same result.

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.

Also recognize thatx[[1,2,3]] will trigger advanced indexing,whereas due to the deprecated Numeric compatibility mentioned above,x[[1,2,slice(None)]] will trigger basic slicing.

Integer array indexing

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

Purely integer array indexing

When the index consists of as many integer arrays as the array being indexedhas dimensions, the indexing is straight forward, but different from slicing.

Advanced indexes 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 result shape is identical to the (broadcast) indexing arrayshapesind_1,...,ind_N.

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=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, as was used in the previous example. This difference is themost important thing to remember about indexing with multiple advancedindexes.

Combining advanced and basic indexing

When there is at least one slice (:), ellipsis (...) ornp.newaxisin the index (or the array has more dimensions than there are advanced indexes),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. A singleadvanced index can for example replace a slice and the result array will bethe same, however, it is a copy and may have a different memory layout.A slice is preferable when it is possible.

Example

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

The easiest way to understand the situation may be to think interms of the result shape. There are two parts to the indexing operation,the subspace defined by the basic indexing (excluding integers) and thesubspace from the advanced indexing part. Two cases of index combinationneed to be distinguished:

  • The advanced indexes are separated by a slice, ellipsis or newaxis.For examplex[arr1,:,arr2].
  • The advanced indexes 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,3,4)-shapedindexingintp array, thenresult=x[...,ind,:] hasshape (10,2,3,4,30) because the (20,)-shaped subspace has beenreplaced with a (2,3,4)-shaped broadcasted indexing subspace. Ifwe leti, j, k loop over the (2,3,4)-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.

Boolean array indexing

This advanced indexing occurs when obj 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 arrayfilled with the elements ofx corresponding to theTruevalues ofobj. The search order will berow-major,C-style. Ifobj hasTrue values at entries that are outsideof the bounds ofx, then an index error will be raised. Ifobj issmaller thanx it is identical to filling it withFalse.

Example

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 not 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 straight forward. Care must only be taken to make sure that theboolean index hasexactly as many dimensions as it is supposed to workwith.

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]])

But ifrowsum would have two dimensions as well:

>>>rowsum=x.sum(-1,keepdims=True)>>>rowsum.shape(3, 1)>>>x[rowsum<=2,:]# failsIndexError: too many indices>>>x[rowsum<=2]array([0, 1])

The last one giving only the first elements because of the extra dimension.Comparerowsum.nonzero() to understand this example.

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=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 or 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]])

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 handx[...] 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.

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. Alsorecord 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']]. Currently this returns a newarray containing a copy of the values in the fields specified in the list.As of NumPy 1.7, returning a copy is being deprecated in favor of returninga view. A copy will continue to be returned for now, but a FutureWarningwill be issued when writing to the copy. If you depend on the currentbehavior, then we suggest copying the returned array explicitly, i.e. usex[[‘field-name1’,’field-name2’]].copy(). This will work with both past andfuture versions of NumPy.

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

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.

Table Of Contents

Previous topic

numpy.dtype.__setstate__

Next topic

Iterating Over Arrays

Quick search

  • © Copyright 2008-2018, The SciPy community.
  • Last updated on Jul 24, 2018.
  • Created usingSphinx 1.6.6.

[8]ページ先頭

©2009-2025 Movatter.jp