As well as accessing arrays with explicit index numbers, NumPy supports a slice notation
that is very similar to lists and tuples in standard Python. However, because an array can
have a rank greater than one, like a matrix which has both rows and columns, then a slice
expression may be specified for each of the array dimensions, and a comma is used to
separate the expressions for the different dimensions:
x = numpy.array([[1,2,3], [4,5,6]])
x[0] # array([1, 2, 3]) – row zero
x[0,:] # array([1, 2, 3]) – row zero, as above
x[:,2] # array([3, 6]) – column two
x[-1,:] # array([4, 5, 6]) – last row
x[:,1:] # array([[2, 3],[5, 6]]) – column one onwards
x[1,0:2] # array([4, 5]) – row one, first two columns
x[::-1,:] # array([[4, 5, 6],[1, 2, 3]]) – reversed rows
x[:,(2,1,0)] # array([[3, 1, 2],[6, 4, 5]]) – new column order
Note that the last example listed above, where the columns of the matrix are shuffled
into a new order by specifying a tuple of indices, provides a way of sorting a matrix so
that its rows or columns appear in numerical order, comparing values at selected index.
Here we use numpy.argsort() to get an array of indices (idx) that represents the order of
the numerical values in column one of x. These indices are then used to make a new
matrix with sorted rows:
x = numpy.array([[4,4], [5,1], [8,3], [7,2]])
idx = numpy.argsort(x[:,1]) # array([1, 3, 2, 0]) – column one order
x[idx,:] # array([[5,1], [7,2], [8,3], [4,4]])
# re-ordered rows, by column one value
We can use the array index and slice notation not only to extract values, but also to
assign values:
x = numpy.array([[1,1,1], [1,1,1], [1,1,1]])
x[1] = (2,3,4) # x; array([[1,1,1], [2,3,4], [1,1,1]])
# new row one
x[:,2] = (5,6,7) # x; array([[1,1,5], [2,3,6], [1,1,7]])
# new column two
y = numpy.zeros((2,2))
x[:2,:2] = y # x; array([[0,0,5], [0,0,6], [1,1,7]])
# replace 2 x 2 elements with 0
x[:,:] = 3 # x; array([[3,3,3], [3,3,3], [3,3,3]])
# replace all elements with 3
NumPy arrays have a number of inbuilt functions (methods) which can be accessed
from them using the dot notation. Where appropriate we can often specify which axis (e.g.
rows or columns for a matrix) to operate on:
x = numpy.array([[3,6],
[2,1],
[5,4]])
x.min() # 1 ; minimum value
x.max() # 6 ; maximum value
x.max(0) # array([5,6]) ; maximum value row
x.max(axis=0) # same as above
x.sum() # 21 ; summation of all elements
x.sum(0) # array([10, 11]) ; add rows together
x.sum(1) # array([9, 3, 9]) ; add columns together
x.mean() # 3.5 ; the mean value of the elements
x.mean(1) # array([4.5, 1.5, 4.5]) # mean of each row
Note that the specification of the axis argument can be a little confusing until you are
used to the way things work. Thus, for example, although axis 1 refers to columns,
x.sum(1) will add up the elements within each row; it is as if all the columns have been
combined into one.
NumPy cleverly lets you create a new array by changing the shape of an existing array.
For example, to create a 2×3 matrix you can first create a vector of size 6, here using
arange() (the array equivalent of range()), and then just reshape it:
x = numpy.arange(1,7) # array([1, 2, 3, 4, 5, 6])
x = x.reshape((2, 3)) # array([[1, 2, 3], [4, 5, 6]])
Of course the reshaping only works if the total size matches. You can even, for
example, reshape a 2×3 matrix into a 3×2 matrix:
y = x.reshape((3, 2)) # array([[1, 2], [3, 4], [5, 6]])
Note that this does not reshape x itself but creates a new array with the new shape.
Also, the reshaping we have just done here is not the same as the transpose of the matrix,
where rows and columns are switched. The transpose of the matrix is given by:
y = x.T # array([[1, 4], [2, 5], [3, 6]])
or equivalently
y = x.transpose() # array([[1, 4], [2, 5], [3, 6]])
Matrix multiplication is exceedingly simple in NumPy. If you have two matrices x and
y then their matrix product is obtained using the dot() function:
8
x = numpy.array(((1,1),(1,0)))
y = numpy.array(((0,1),(1,1)))
z = numpy.dot(x, y) # array([[1, 2], [0, 1]])
What the above is saying in terms of matrices is that
It might seem tempting to just use ‘*’ for multiplication, and although this is a valid
operation in NumPy, it just multiplies the two matrices together element by element, so is
not the same as matrix multiplication:
z = x * y # array([[0, 1], [1, 0]])
There is actually a specific matrix data type in NumPy that does allow ‘*’ to be used for
matrix multiplication, but it is not used very often and it is generally best to stick with the
commonly used array. NumPy also has functions that do some of the trickier operations
involved in linear algebra; for example, there is a function to calculate the inverse of a
matrix. This is accessed via the linalg sub-module:
x = numpy.array(((1,1),(1,0)))
y = numpy.linalg.inv(x) # array([[0., 1.], [1., -1.]])
Note that the inverse is floating point even if the original matrix is integer. What the
above is saying in terms of matrices is that
There is much more to the linalg module, as described in the NumPy documentation,
9
including various decompositions and eigenvector calculation.
Do'stlaringiz bilan baham: