John Paul Mueller

Algorithms For Dummies


Скачать книгу

vectors as a whole, which makes numpy incredibly useful and less prone to errors that can occur when using programming constructs such as loops to perform the same task. For example, when starting with myVect = np.array([1, 2, 3, 4]), myVect + 1 produces an output of array([2, 3, 4, 5], dtype=int16). Note that the output tells you specifically which data type is in use. As you might expect, myVect - 1 produces an output of array([0, 1, 2, 3], dtype=int16).

       a = np.array([1, 2, 3, 4])b = np.array([2, 2, 4, 4]) print(a == b)print(a < b)

      The output in this case is:

       [False True False True][ True False True False]

      Starting with two vectors, a and b, the code checks whether the individual elements in a equal those in b. In this case, a[0] doesn't equal b[0]. However, a[1] does equal b[1]. The output is a vector of type bool that contains True or False values based on the individual comparisons.

      Logical operations rely on special functions. You check the logical output of the Boolean operators AND, OR, XOR, and NOT. Here is an example of the logical functions:

       a = np.array([True, False, True, False])b = np.array([True, True, False, False]) print(np.logical_or(a, b))print(np.logical_and(a, b))print(np.logical_not(a))print(np.logical_xor(a, b))

      When you run this code, you see these outputs:

       [ True True True False][ True False False False][False True False True][False True True False]

      You can read more about the logic functions at https://numpy.org/doc/stable/reference/routines.logic.html.

      Performing vector multiplication

      Adding, subtracting, or dividing vectors occurs on an element-by-element basis, as described in the previous section. However, when it comes to multiplication, things get a little odd. In fact, depending on what you really want to do, things can become quite odd indeed. Consider the sort of multiplication discussed in the previous section. Both myVect * myVect and np.multiply(myVect, myVect) produce an element-by-element output of [ 1, 4, 9, 16] when starting with an array of [1, 2, 3, 4].

      

Unfortunately, an element-by-element multiplication can produce incorrect results when working with algorithms. In many cases, what you really need is a dot product, which is the sum of the products of two number sequences. When working with vectors, the dot product is always the sum of the individual element-by-element multiplications and results in a single number. For example, myVect.dot(myVect) results in an output of 30. If you sum the values from the element-by-element multiplication, you find that they do indeed add up to 30. The discussion at https://www.mathsisfun.com/algebra/vectors-dot-product.html tells you about dot products and helps you understand where they might fit in with algorithms. You can learn more about the linear algebra manipulation functions for numpy at https://numpy.org/doc/stable/reference/routines.linalg.html.

      Creating a matrix is the right way to start

      Many of the same techniques you use with vectors also work with matrixes. To create a basic matrix, you simply use the array() function as you would with a vector, but you define additional dimensions. A dimension is a direction in the matrix. For example, a two-dimensional matrix contains rows (one direction) and columns (a second direction). The array call myMatrix = np.array([[1,2,3], [4,5,6], [7,8,9]]) produces a matrix containing three rows and three columns, like this:

       [[1 2 3] [4 5 6] [7 8 9]]

      Note how you embed three lists within a container list to create the two dimensions. To access a particular array element, you provide a row and column index value, such as myMatrix[0, 0] to access the first value of 1. You can find a full listing of vector and matrix array-creation functions at https://numpy.org/doc/stable/reference/routines.array-creation.html.

The NumPy package supports an actual matrix class. The matrix class supports special features that make it easier to perform matrix-specific tasks. You discover these features later in the chapter. For now, all you really need to know is how to create a matrix of the matrix data type. The easiest method is to make a call similar to the one you use for the array function, but using the mat function instead, such as myMatrix = np.mat([[1,2,3], [4,5,6], [7,8,9]]), which produces the following matrix:

       [[1 2 3] [4 5 6] [7 8 9]]

      To determine that this actually is a matrix, try print(type(myMatrix)), which outputs <class 'numpy.matrix'>. You can also convert an existing array to a matrix using the asmatrix() function. Use the asarray() function to convert a matrix object back to an array form.

      

The only problem with the matrix class is that it works on only two-dimensional matrixes. If you attempt to convert a three-dimensional matrix to the matrix class, you see an error message telling you that the shape is too large to be a matrix.

      Multiplying matrixes

      Multiplying two matrixes involves the same concerns as multiplying two vectors (as discussed in the “Performing vector multiplication” section, earlier in this chapter). The following code produces an element-by-element multiplication of two matrixes:

       a = np.array([[1,2,3],[4,5,6]])b = np.array([[1,2,3],[4,5,6]]) print(a*b)

      The output looks like this:

       [[ 1 4 9] [16 25 36]]

      

Note that a and b are the same shape: two rows and three columns. To perform an element-by-element multiplication, the two matrixes must be the same shape. Otherwise, you see an error message telling you that the shapes are wrong. As with vectors, the multiply() function also produces an element-by-element result.

       a = np.array([[1,2,3],[4,5,6]])b = np.array([[1,2,3],[3,4,5],[5,6,7]]) print(a.dot(b))

      with an output of:

       [[22 28 34] [49 64 79]]