Introduction to NumPy and Matplotlib Chapter 1: Introduction Chapter 2: NumPy arrays Chapter 3: Array operations [3.1] Numerical ranges [3.2] Mathematical operations [3.3] Mathematical operations [3.4] Indexing arrays [3.5] Boolean indexing [3.6] Exercise Chapter 4: Array reshaping Chapter 5: Array manipulation Chapter 6: NumPy functions Chapter 7: Miscellaneous Chapter 8: NumPy recap and exercises Chapter 9: Matplotlib Chapter 3: Array operations Mathematical operations face Josiah Wang It is probably easier to explore these operators by using them directly! Try answering the following quiz questions. 1 2 3 4 5 6 7 8 ❮ ❯ Question 1 Fill in the blank in the code below to perform the following multiplication operation: 3\cdot\begin{bmatrix}1 & 2 & -3\\-2 & 1 & 3\end{bmatrix}=\begin{bmatrix}3 & 6 & -9\\-6 & 3 & 9\end{bmatrix} Your answer should look something like x+y or np.add(x, y). x = 3 y = np.array([[1, 2, 3], [-2, 1, 3]]) z = ________ Output x*y Explanation: You can multiply a np.array with a scalar using the * operator. It will multiply each element of the np.array with the scalar. You can also use np.multiply(x, y). Check answer! Question 2 Fill in the blank in the code below with the correct operator for the following element-wise multiplication operation: \begin{bmatrix}1 & 2\\3 & 4\end{bmatrix}\odot\begin{bmatrix}2 & 3\\4 & 5\end{bmatrix}=\begin{bmatrix}2 & 6\\12 & 20\end{bmatrix} Your answer should look something like x+y or np.add(x, y). x = np.array([[1, 2], [3, 4]]) y = np.array([[2, 3], [4, 5]]) z = ________ Output x*y Explanation: Again, using the * operator between two np.arrays of the same shape will result in an element-wise multiplication. If you are a MATLAB user, note that this is equivalent to the .* operator in MATLAB. Check answer! Question 3 Fill in the blank in the code below with the correct operator for the following matrix multiplication. Note the difference between this and the elementwise multiplication from the previous question! \begin{bmatrix}1 & 2\\3 & 4\end{bmatrix} \begin{bmatrix}2 & 3\\4 & 5\end{bmatrix}=\begin{bmatrix}10 & 13\\22 & 29\end{bmatrix} Your answer should look something like x+y or np.add(x, y). x = np.array([[1, 2], [3, 4]]) y = np.array([[2, 3], [4, 5]]) z = ________ Output x@y Explanation: Using the @ operator for matrix multiplication. You can also use np.matmul(x, y) if you prefer something more descriptive. Remember, use @ for matrix multiplication, and * for elementwise multiplication. Look back at the previous question now if you are still not sure how they are different! If you are a MATLAB user, note that @ in NumPy is equivalent to the * operator in MATLAB, and * in NumPy is .* in MATLAB. So don't get these mixed up either! Check answer! Question 4 What is the output of the following code? Enter "Error" if it results in an error. Write your answer as if printed out by NumPy without the comma in between the elements, e.g. [1 2]. x = np.array([6, 8]) y = np.array([2, 4]) z = x / y print(z) Output [3. 2.] Explanation: The code above performs elementwise division, so [6/2, 8/4]. Note that the dtype is a float and not int - this is the same as in Python! Of course, you can also divide by a scalar, e.g. x / 2 to get [6/2, 8/2]. Check answer! Question 5 What is the output of the following code? Enter "Error" if it results in an error. If your answer is a np.array, write your answer as if printed out by NumPy without the comma in between the elements, e.g. [1 2]. x = np.array([1, 2, 3]) y = np.array([2, 3, 4]) z = np.dot(x, y) print(z) Output 20 Explanation: The code above computes the dot product between two vectors (or rather two 1D np.arrays). So it is \begin{bmatrix}1 & 2 & 3\end{bmatrix} \cdot \begin{bmatrix}2 & 3 & 4\end{bmatrix}= (1 \times 2) + (2 \times 3) + (3 \times 4) = 20. Check answer! Question 6 What is the output of the following code? Enter "Error" if it results in an error. Write your answer as if printed out by NumPy without the comma in between the elements, e.g. [1 2]. x = np.array([[1, 2, 3]]) y = np.array([[4, 5]]) z = x - y print(z) Output Error Explanation: A ValueError is raised with the message: operands could not be broadcast together with shapes (1,3) (1,2). It is basically saying the shape of the two matrices are incompatible to perform the operation. Check answer! Question 7 What is the output of the following code? Enter "Error" if it results in an error. Write your answer as if printed out by NumPy without the comma in between the elements and without new lines, e.g. [[1 2] [3 4]]. x = np.array([[1, 2], [3, 4]]) y = np.array([[2, 5]]) z = x * y print(z) Output [[2 10] [6 20]] Explanation: This one actually works, despite the arrays not being the same dimensions. NumPy actually performs what is called array broadcasting. It will try to automatically make the arrays compatible if possible. In this example, it replicates the rows of y along axis 0: \begin{bmatrix}1 & 2\\3 & 4\end{bmatrix}\odot\begin{bmatrix}2 & 5\\2 & 5\end{bmatrix}=\begin{bmatrix}2 & 10\\6 & 20\end{bmatrix} This broadcasting process is explained in the official documentation. Check answer! Question 8 What is the output of the following code? Enter "Error" if it results in an error. Write your answer as if printed out by NumPy without the comma in between the elements and without new lines, e.g. [1 2 3 4]. x = np.array([2, 3, 4]) y = x < 3 print(y) Output [ True False False] Explanation: You can also perform element-wise comparison with np.arrays, with comparison operators like <, ==, >= etc. just like in Python. Since the comparison operators will result in a boolean expression, each element will also be of bool. So the result is a np.array with a dtype of bool. You will see later how such operations might be useful! Check answer!