4.7 Slicing Arrays
The standard rules of Python slicing apply to arrays, on a per-dimension basis.
Assuming a 3x3 array:
>>> a = reshape(arange(9),(3,3))
>>> print a
[[0 1 2]
[3 4 5]
[6 7 8]]
The plain [:]
operator slices from beginning to end:
>>> print a[:,:]
[[0 1 2]
[3 4 5]
[6 7 8]]
In other words, [:]
with no arguments is the same as [:]
for
lists -- it can be read ``all indices along this axis''. (Actually, there is
an important distinction; see below.) So, to get the second row along the
second dimension:
Note that what was a ``column'' vector is now a ``row'' vector any ``integer
slice'' (as in the 1 in the example above) results in a returned array with
rank one less than the input array. There is one important distinction between
slicing arrays and slicing standard Python sequence objects. A slice of a
list is a new copy of that subset of the list; a slice of an
array is just a view into the data of the first array. To force a copy, you
can use the copy method. For example:
>>> a = arange (20)
>>> b = a[3:8]
>>> c = a[3:8].copy()
>>> a[5] = -99
>>> print b
[ 3 4 -99 6 7]
>>> print c
[3 4 5 6 7]
If one does not specify as many slices as there are dimensions in an array,
then the remaining slices are assumed to be ``all''. If A is a rank-3
array, then
A[1] == A[1,:] == A[1,:,:]
There is one addition to the slice notation for arrays which does not exist for
lists, and that is the optional third argument, meaning the ``step size'', also
called stride or increment. Its default value is 1, meaning return every
element in the specified range. Alternate values allow one to skip some of the
elements in the slice:
>>> a = arange(12)
>>> print a
[ 0 1 2 3 4 5 6 7 8 9 10 11]
>>> print a[::2] # return every *other* element
[ 0 2 4 6 8 10]
Negative strides are allowed as long as the starting
index is greater than the stopping index:
>>> a = reshape(arange(9),(3,3)) Array Basics
>>> print a
[[0 1 2]
[3 4 5]
[6 7 8]]
>>> print a[:, 0]
[0 3 6]
>>> print a[0:3, 0]
[0 3 6]
>>> print a[2::-1, 0]
[6 3 0]
If a negative stride is specified and the starting or stopping indices are
omitted, they default to ``end of axis'' and ``beginning of axis''
respectively. Thus, the following two statements are equivalent for the array
given:
>>> print a[2::-1, 0]
[6 3 0]
>>> print a[::-1, 0]
[6 3 0]
>>> print a[::-1] # this reverses only the first axis
[[6 7 8]
[3 4 5]
[0 1 2]]
>>> print a[::-1,::-1] # this reverses both axes
[[8 7 6]
[5 4 3]
[2 1 0]]
One final way of slicing arrays is with the keyword "..." This keyword is
somewhat complicated. It stands for ``however many `:' I need depending on the
rank of the object I'm indexing, so that the indices I do specify are at
the end of the index list as opposed to the usual beginning''.
So, if one has a rank-3 array A, then A[...,0]
is the same thing
as A[:,:,0]
, but if B is rank-4, then B[...,0]
is the same
thing as: B[:,:,:,0]
. Only one "..." is expanded in an index
expression, so if one has a rank-5 array C, then C[...,0,...]
is
the same thing as C[:,:,:,0,:]
.
Send comments to the NumArray community.