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]]
[:]
operator slices from beginning to end:
>>> print a[:,:] [[0 1 2] [3 4 5] [6 7 8]]
[:]
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:
>>> print a[:,1] [1 4 7]
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]
A[1] == A[1,:] == A[1,:,:]
>>> 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]
>>> 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]
>>> 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]]
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,:]
.
When assigment source and destination locations overlap, i.e. when an array is assigned onto itself at overlapping indices, it may produce something "surprising":
>>> n=numarray.arange(36) >>> n[11:18]=n[7:14] >>> n array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 7, 8, 9, 10, 7, 8, 9, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35])
If the slice on the right hand side (RHS) is AFTER that on the left hand side (LHS) for 1-D array, then it works fine:
>>> n=numarray.arange(36) >>> n[1:8]=n[7:14] >>> n array([ 0, 7, 8, 9, 10, 11, 12, 13, 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, 35])
Actually, this behavior can be undedrstood if we follow the pixel by pixel copying logic. Parts of the slice start to get the "updated" values when the RHS is before the LHS.
An easy solution which is guaranteed to work is to use the copy() method on the righ hand side:
>>> n=numarray.arange(36) >>> n[11:18]=n[7:14].copy() >>> n array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 7, 8, 9, 10, 11, 12, 13, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35])
Send comments to the NumArray community.