{
"cells": [
{
"cell_type": "markdown",
"id": "c938aac4",
"metadata": {
"id": "5mHvWJM9WC5S"
},
"source": [
" \n",
"\n",
"# **Array (matrix) operations in NumPy**"
]
},
{
"cell_type": "markdown",
"id": "ad2cc125",
"metadata": {
"id": "8eIlb-CEaU61"
},
"source": [
"## Arithmetic operators"
]
},
{
"cell_type": "markdown",
"id": "448283b7",
"metadata": {
"id": "E8nI64UMj_wE"
},
"source": [
"As with scalars, we can use some basic arithmetic operators to manipulate a vector or a matrix in NumPy. The following operators can be used: `+`, `-`, `/`, `*`, `**`,`%`. It's very important to note that these operators are performed **element-wise** on an array."
]
},
{
"cell_type": "markdown",
"id": "f997910e",
"metadata": {
"id": "0ruNHyQ7TJ29"
},
"source": [
"|Function | Description|\n",
"|--|--|\n",
"|``np.add(arr1, arr2)``| addition|\n",
"|``np.subtract(arr1, arr2)``|subtraction|\n",
"|``np.multiply(arr1, arr2/number)``|multiplication|\n",
"|``np.divide(arr1, arr2/number)``|division|\n",
"|``np.power(arr1, number)``|power|\n",
"|``np.remainder(arr1, number)``|remainder|\n",
"|``np.square(arr1)``|square of each element in the array|\n",
"|``np.sqrt(arr1)``|square root of each element in the array|\n",
"|``np.sum(arr1)``|sum of elements in the array|"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "0620c433",
"metadata": {
"id": "O1vJu3wPVTU0"
},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"a = np.array([1,3,5]) #1D array\n",
"b = np.array([5,3,1]) #1D array\n",
"c = np.array([[2,6,10],[1,3,5]]) #2D array\n",
"d = np.array([[1,1,1],[2,2,2]]) #2D array"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "cb983ad6",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "5Wl9EbISCvmC",
"outputId": "0ec10fb5-2b1b-4145-bb58-94250c8b578d"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[6 6 6]\n"
]
}
],
"source": [
"addition = a + b # or: np.add(a, b)\n",
"print(addition)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "72e5c5f5",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "oN8fjWJDCu21",
"outputId": "d796d512-f90b-4018-9dd5-ef8b9eca33d6"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[ 1 5 9]\n",
" [-1 1 3]]\n"
]
}
],
"source": [
"subtraction = c - d # or: np.subtract(a, b)\n",
"print(subtraction)"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "072075f1",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "ZwfzxmANCfIE",
"outputId": "ff959ae8-a5ff-4e9a-fa97-294b72803d96"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[12 36 60]\n",
" [ 6 18 30]]\n"
]
}
],
"source": [
"multiplication = c * 6 # or: np.multiply(a, 6)\n",
"print(multiplication)"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "68f106ee",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "V5kcQIMBCfC5",
"outputId": "0aa8fab3-6a22-4808-ae6e-fda9bad90309"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0.33333333 1. 1.66666667]\n"
]
}
],
"source": [
"division = a / 3 # or: np.divide(a, 3)\n",
"print(division)"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "e2a551ff",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "my4Dt8lqCe70",
"outputId": "3eb2cfae-7e7e-48e2-a2cc-3e790a9dbcaf"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[1 1 1]\n",
" [4 4 4]]\n"
]
}
],
"source": [
"power = d ** 2 # or: np.power(a, 2)\n",
"print(power)"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "962e1861",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "tJadPaWuCe0U",
"outputId": "fa137219-0bfb-4cf9-9c88-007d254bc15b"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[1 1 1]\n"
]
}
],
"source": [
"remainder = a % 2 # or: np.remainder(a, b) # or: np.mod(a, b)\n",
"print(remainder)"
]
},
{
"cell_type": "markdown",
"id": "c1e92b73",
"metadata": {
"id": "OQ49B3cyjuTC"
},
"source": [
"## Broadcasting\n",
"\n",
"The element-wise operations we introduced above only work on arrays of similar shapes. However, in some cases NumPy can transform arrays so that they all have similar shapes. NumPy does this by stretching or \"copying\" the dimensions with size=1 to match the dimension of the matrix.\n",
"If interested, you can read more on this topic [here](https://numpy.org/doc/stable/user/basics.broadcasting.html). Below are some examples."
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "2014d3a1",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "sSDX2pG7e-aw",
"outputId": "c2d6540b-30bc-4ae8-c871-dca312ab7cc0"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[2 4 6]\n",
" [3 5 7]]\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"a = np.array([1,3,5]) #1D array\n",
"c = np.array([[2,6,10],[1,3,5]]) #2D array\n",
"d = np.array([[1,1,1],[2,2,2]]) #2D array\n",
"\n",
"addition = a + d\n",
"print(addition)"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "0e78497a",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "F3HHBHkyDBTL",
"outputId": "d340c2db-8e79-46d4-ed1b-e340d9e8f417"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[2. 2. 2.]\n",
" [1. 1. 1.]]\n"
]
}
],
"source": [
"division = c / a\n",
"print(division)"
]
},
{
"cell_type": "markdown",
"id": "22700fc2",
"metadata": {
"id": "WsMgdJKpaYYR"
},
"source": [
"## Logical expressions"
]
},
{
"cell_type": "markdown",
"id": "60c66f90",
"metadata": {
"id": "8QNpIe1UmHRI"
},
"source": [
"Similarly, we can use logical expressions to filter and manipulate data in a Numpy array. When using Numpy we have multiple options for using logical operators for **AND**, **OR**, and **NOT**. We can implement prewritten **Numpy** functions or we can use **&** or **\\***, **|** or **+**, and **!** or **-**.\n",
"\n",
"| Operator | Example | Arithmetic |\n",
"|--|--|--|\n",
"| ``AND, &, *`` | ``True * True = True``
``True * False = False``
``False * False = False`` | ``1 * 1 = 1``
``1 * 0 = 0``
``0 * 0 = 0`` |\n",
"| ``OR, \\|, +`` | ``True + True = True``
``True + False = True``
``False + False = False`` | ``1 + 1 = 1``
``1 + 0 = 1``
``0 + 0 = 0`` |\n",
"| ``NOT, !, -``|``1 - True = False``
``1 - False = True``
``not True = False`` | ``1 - 1 = 0``
``1 - 0 = 1``
``1 - 1 = 0`` |\n",
"\n",
"As an example, consider the two floating point arrays:\n",
"`a = [-1,2,-3,4,5,6,7]`, and `b=[7,6,5,4,-3,2,-1]`\n",
"\n",
"The following table shows some operations which can be done using logical expressions:\n",
"\n",
"|Expression | Resulting array| Explanation|\n",
"|--|--|--|\n",
"|``a > 0``| ``[False True False True True True True]``| ``True`` if element greater than 0|\n",
"|``(a > 0) * (a < 10)``| ``[False True False True True True True]``| Multiplication with booleans works as **AND** |\n",
"|``(a > 0) + ( a >= 10)``|``[False True False True True True True]``| Summing booleans works as **OR**|\n",
"|``a[a > 0]``|``[2 4 5 6 7]``| Select the elements of ``a`` where ``a > 0`` is ``True``|\n",
"|``b[a > 0]``|``[ 6 4 -3 2 -1]``| Select the elements of ``b`` where ``a > 0`` is ``True``|\n",
"|``np.where(a > 0)[0]``|``[1 3 4 5 6]``| Return **a list of indices** where ``(a > 0)`` was ``True``|"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "5ed520ed",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "yHHodOHaKXHJ",
"outputId": "f00b4d65-6af4-478c-b770-171d120077ab"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[False True False True True True True]\n",
"[False True False True True True True]\n",
"[False True False True True True True]\n",
"[2 4 5 6 7]\n",
"[ 6 4 -3 2 -1]\n",
"[1 3 4 5 6]\n"
]
}
],
"source": [
"a = np.array([-1,2,-3,4,5,6,7]) #1D array\n",
"b = np.array([7,6,5,4,-3,2,-1]) #1D array\n",
"\n",
"# True if element greater than 0\n",
"print(a > 0)\n",
"\n",
"# Multiplication with booleans works as AND\n",
"print((a>0) * (a<10))\n",
"\n",
"# Summing booleans works as OR\n",
"print((a>0) + (a>=10))\n",
"\n",
"# Select the elements of a where a > 0 is 'True'\n",
"print(a[a>0])\n",
"\n",
"# Select the elements of b where a > 0 is 'True'\n",
"print(b[a>0])\n",
"\n",
"# Return a list of indices where (a > 0) was 'True'\n",
"print(np.where(a>0)[0])"
]
},
{
"cell_type": "markdown",
"id": "aafc94d1",
"metadata": {
"id": "rhSVNBCZugMn"
},
"source": [
"## Some useful statistical operations\n",
"\n",
"Below is a list of some other operations that can be very usefull when working with matrices.\n",
"\n",
"| Operator\t | Output |\n",
"|------------------------|---------------------------------------|\n",
"| ``np.mean(A, axis=n)`` | the arithmetic mean along the specified axis|\n",
"| ``np.std(A, axis=n)`` | the standard deviation along the specified axis|\n",
"| ``np.min(A, axis=n)`` | the minimum value along a specified axis |\n",
"| ``np.max(A, axis=n)``| the maximum value along a specified axis |\n",
"| ``np.sum(A, axis=n)``| the sum of array elements over a given axis |\n",
"| ``np.argmin(A, axis=n)`` | the indices of the maximum values along an axis |\n",
"| ``np.argmax(A, axis=n)``| the indices of the maximum values along an axis |\n",
"| | |"
]
},
{
"cell_type": "markdown",
"id": "1a2c92ef",
"metadata": {
"id": "gZVPzAxyA5NF"
},
"source": [
"In NumPy, an **axis** is a dimension along which an operation is performed. For a two-dimensional array, there are two axes:\n",
"* Axis 0 = Rows: This axis runs vertically downwards. It represents the direction along which you move from one row to the next. When you perform operations along axis 0, you are operating across rows. For example, **calculating the mean along axis 0 means computing the mean of each column.**\n",
"* Axis 1 = Columns: This axis runs horizontally across the matrix. It represents the direction along which you move from one column to the next. When you perform operations along axis 1, you are operating across columns. For example, **calculating the mean along axis 1 means computing the mean of each row.**\n",
"\n",
"Check the examples below to gain a better understanding of the concept. You can also test and compare different functions for different axes by yourself."
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "8961a98a",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "Dk43Ckza-C5w",
"outputId": "1c7797c4-d88c-4020-cbfe-66ede2e8d3f2"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The arithmetic mean of all elements: \n",
"5.5\n",
"Mean along axis 0: \n",
"[3.5 4.5 5.5 6.5 7.5]\n",
"Mean along axis 1: \n",
"[3. 8.]\n",
"The standard deviation: \n",
"2.8722813232690143\n",
"The minimum value: \n",
"1\n",
"The minimum value along axis 1: \n",
"[1 6]\n",
"The maximum value: \n",
"10\n",
"The sum of array elements: \n",
"55\n",
"The indices of the minimum values along an axis 1: \n",
"[0 0]\n",
"The indices of the maximum values along axis 0: \n",
"[1 1 1 1 1]\n"
]
}
],
"source": [
"matrix = np.array([[1, 2, 3, 4, 5],\n",
" [6, 7, 8, 9, 10]])\n",
"\n",
"# The arithmetic mean of all elements\n",
"print(\"The arithmetic mean of all elements: \")\n",
"print(np.mean(matrix))\n",
"\n",
"# Mean along axis 0 (mean for each column)\n",
"print(\"Mean along axis 0: \")\n",
"print(np.mean(matrix, axis=0))\n",
"\n",
"# Mean along axis 1 (mean for each row)\n",
"print(\"Mean along axis 1: \")\n",
"print(np.mean(matrix, axis=1))\n",
"\n",
"# The standard deviation\n",
"print(\"The standard deviation: \")\n",
"print(np.std(matrix))\n",
"\n",
"# The minimum value\n",
"print(\"The minimum value: \")\n",
"print(np.min(matrix))\n",
"\n",
"# The minimum value along axis 1\n",
"print(\"The minimum value along axis 1: \")\n",
"print(np.min(matrix, axis=1))\n",
"\n",
"# The maximum value\n",
"print(\"The maximum value: \")\n",
"print(np.max(matrix))\n",
"\n",
"# The sum of array elements\n",
"print(\"The sum of array elements: \")\n",
"print(np.sum(matrix))\n",
"\n",
"# The indices of the minimum values along axis 1\n",
"print(\"The indices of the minimum values along an axis 1: \")\n",
"print(np.argmin(matrix, axis=1))\n",
"\n",
"# The indices of the maximum values along axis 0\n",
"print(\"The indices of the maximum values along axis 0: \")\n",
"print(np.argmax(matrix, axis=0))"
]
},
{
"cell_type": "markdown",
"id": "3165c777",
"metadata": {
"id": "6Arnt0pYac9o"
},
"source": [
"## Matrix operations (linear algebra):\n",
"\n",
"A large part of the mathematical knowledge required for different fields of electrical engineering comes from linear algebra. Matrix operations play a significant role in linear algebra. Below is a list of common matrix operations you can perform in NumPy. Note that matrix A is of size `(m,k)` and B is of size `(k,n)`.\n",
"\n",
"| Operation| Mathematical expression\t| NumPy expression | Output shape |\n",
"|-----|---|------|--|\n",
"|Dot product (vectors) | $a \\cdot b$ | ``a.dot(b)``| scalar|\n",
"|Matrix multiplication| $A \\times B$| ``A@B`` or ``A.dot(B)``| ``(m,k)@(k,n)=(m,n)``|\n",
"|Transpose|$A^T$|``A.transpose()`` or ``A.T``| ``(m,n).T=(n,m)``|\n",
"|Inverse|$A^{-1}$|``np.linalg.inv(A)``|``(m,m)^-1=(m,m)``, only if ``k=m``|\n",
"|Pseudo-inverse| $A^{+}$| ``np.linalg.pinv(A)``|``(m,k)^-1=(k,m)``|\n",
"|Determinant|$|A|$|``np.linalg.det(A)``|scalar|\n",
"|Rank |$rank(A)$|``np.linalg.matrix_rank(A)``|scalar|\n",
"|Trace|$tr(A)$| ``A.trace()`` |scalar|\n",
"\n",
"Note that the sub-module `numpy.linalg` implements basic linear algebra, such as solving linear systems, singular value decomposition, etc. However, it is recommend to use `scipy.linalg` to guarantee efficient compilation."
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "0aa6ac14",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "uopCEjv2yzel",
"outputId": "a5e78000-f82c-4b2e-b529-c6a69ac14674"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"A @ B = [[ 7 13]\n",
" [22 39]\n",
" [16 29]]\n",
"A^-1 = [[-7. 2.]\n",
" [ 4. -1.]]\n",
"A^+ = [[ 0.20512821 -0.14102564 0.16666667]\n",
" [-0.11794872 0.24358974 -0.03333333]]\n",
"A^+ = [[-7. 2.]\n",
" [ 4. -1.]]\n",
"A^T = [[3 2 4]\n",
" [1 5 3]]\n",
"rank (A) = 2\n",
"tr(A ): 8\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
"# A = 3x2 and B = 2x2 matrix\n",
"A=np.array([[3, 1],\n",
" [2, 5],\n",
" [4, 3]])\n",
"B=np.array([[1,2],\n",
" [4,7]]) # B is a square matrix\n",
"\n",
"# Matrix multiplication\n",
"mat_mul=A@B # or: A.dot(B)\n",
"print(\"A @ B = \",mat_mul)\n",
"\n",
"inverse = np.linalg.inv(B)\n",
"print(\"A^-1 = \",inverse)\n",
"\n",
"determinant = np.linalg.pinv(A)\n",
"print(\"A^+ = \",determinant)\n",
"\n",
"determinant = np.linalg.det(B)\n",
"print(\"A^+ = \",inverse)\n",
"\n",
"transpose = A.T\n",
"print(\"A^T = \",transpose)\n",
"\n",
"rank = np.linalg.matrix_rank(A)\n",
"print(\"rank (A) = \",rank)\n",
"\n",
"trace = A.trace()\n",
"print('tr(A ):',trace)"
]
},
{
"cell_type": "markdown",
"id": "0c4de3fc",
"metadata": {
"id": "XkXKBRENGtkG"
},
"source": [
"## Exercises"
]
},
{
"cell_type": "markdown",
"id": "3a82c93f",
"metadata": {
"id": "rmDGnKcoEf3_"
},
"source": [
"### **Exercise: Euclidean distance**\n",
"\n",
"Write a Python program to find the Euclidean distance between the two given one-dimensional arrays. The mathematical Euclidian distance is usually given by the formula:\n",
"\n",
"$\\sqrt{((x_2-x_1)^2 + (y_2-y_1)^2)}$\n",
"\n",
"For one-dimensional arrays, you can think of the arrays as `[a1, b1, c1]` and `[a2, b2, c2]`, and the Euclidean distance is:\n",
"\n",
"$\\sqrt{((a_2-a_1)^2 +(b_2-b_1)^2 + (c_2-c_1)^2)}$\n",
"\n",
"💡Hint: you can use `np.square()`, `np.sum()` and `np.sqrt()`.\n",
"\n",
"💡Don't forget to print and check your progress in the intermediate steps to ensure you are on the right track."
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "9dad27c8",
"metadata": {
"id": "xV55ZKfjD7uy"
},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"# Example arrays\n",
"array1 = np.array([1, 2, 3])\n",
"array2 = np.array([4, 5, 6])"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "4f0939a1",
"metadata": {
"id": "grKIwXrVD8kR"
},
"outputs": [
{
"ename": "SyntaxError",
"evalue": "invalid syntax (3733689348.py, line 2)",
"output_type": "error",
"traceback": [
" \u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[14]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[31m \u001b[39m\u001b[31msquared_diff = # your code here\u001b[39m\n ^\n\u001b[31mSyntaxError\u001b[39m\u001b[31m:\u001b[39m invalid syntax\n"
]
}
],
"source": [
"# Find the squared difference: first subtract the arrays and then find the difference\n",
"squared_diff = # your code here\n",
"print(squared_diff)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "19284236",
"metadata": {
"id": "5nh_pv-OD8aB"
},
"outputs": [],
"source": [
"# Sum of the squared distances:\n",
"sum_squared_diff = # your code here\n",
"print(sum_squared_diff)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "bff2a70a",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "EbBrF0eclxof",
"outputId": "69f7a26f-9774-46f9-ff26-bc668e8f72b9"
},
"outputs": [],
"source": [
"# Square root of the sum:\n",
"euclidean_distance = # your code here\n",
"print(euclidean_distance)\n",
"\n",
"print(f\"Euclidean Distance between array1 and array2: {euclidean_distance:.2f}\")"
]
},
{
"cell_type": "markdown",
"id": "898edefb",
"metadata": {
"id": "6k1c7DlIG3R_"
},
"source": [
"____\n",
"### **Exercise: Solving a linear system of equations**\n",
"\n",
"You are tasked with solving the following system of linear equations for the variables x, y, and z:\n",
"\n",
"$$\n",
"\\begin{aligned}\n",
"2x + y - 3z &= 8 \\\\\n",
"4x + 5y + z &= 20 \\\\\n",
"x - 2y + z &= -2\n",
"\\end{aligned}\n",
"$$\n",
"\n",
"Pepresent this system of linear equations as a matrix multiplication, i.e., A * X = B, where:\n",
"A is the coefficient matrix,\n",
"X is the column vector of variables (x, y, z), and\n",
"B is the column vector of constants on the right-hand side.\n",
"Complete the definition of the A and B arrays in the provided code below.\n",
"Find the inverse of matrix A using NumPy's `np.linalg.inv()`. Then, use it to find the correct values for the variables x, y, and z."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "10e580f6",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "cXoFzsrEDpLg",
"outputId": "c8fa5bb7-e7b8-4c0c-ef86-2f3e09a8af61"
},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"# Define the coefficient matrix A and the constant vector B\n",
"A = # your code here\n",
"B = # your code here\n",
"\n",
"# Task 1: Calculate the inverse of matrix A\n",
"A_inv = # your code here\n",
"\n",
"# Task 2: Solve for vector X using X = A_inv * B\n",
"X = # your code here\n",
"\n",
"# Print the results\n",
"print(\"Inverse of matrix A:\")\n",
"print(A_inv)\n",
"\n",
"print(\"\\nSolution vector X (x, y, z):\")\n",
"print(X)"
]
},
{
"cell_type": "markdown",
"id": "cc6f3204",
"metadata": {
"id": "L97ysgQrzDIu"
},
"source": [
"____\n",
"### **Exercise: Underwater research - analyzing marine animal data**\n",
"\n",
"You are part of a marine biologist team on an underwater research expedition. Your team has collected data on various marine animals. Each marine animal is represented by a row in a matrix, and their measurements are recorded in columns.\n",
"\n",
"Your task is to analyze this data to gain insights into these fascinating creatures.\n",
"\n",
"A 4x4 matrix representing data on four marine animals is given.\n",
"\n",
"The columns represent the following attributes:\n",
"* Size (in meters)\n",
"* Swimming speed (in km/h)\n",
"* Diet variety (number of different food types)\n",
"* Average depth (in meters)\n",
"\n",
"🐋**Tasks:**\n",
"1. Calculate and print the maximum size of any marine animal.\n",
"2. Calculate and print the average swimming speed across all marine animals.\n",
"3. Identify and print the name of the marine animal with the highest diet variety.\n",
"4. Identify and print the names of marine animals that have an average depth below 200 meters.\n",
"\n",
":::{tip}: You can use the `np.where()` function for task 4, as it returns a list of indices where the condition (e.g., ``a < 200``) is met.\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f398bc19",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "FcHICwyfzGYd",
"outputId": "61f84865-d726-41df-d830-8574abd84343"
},
"outputs": [],
"source": [
"import numpy as np\n",
"# Will be given\n",
"# A 4x4 matrix for 4 marine animals and 4 attributes\n",
"# Rows represent marine animals, columns represent [size, speed, diet variety, depth]\n",
"\n",
"data_matrix = np.array([\n",
" [2.5, 40, 3, 150], # Animal 1\n",
" [1.2, 25, 1, 300], # Animal 2\n",
" [3.0, 55, 5, 100], # Animal 3\n",
" [0.8, 20, 2, 250] # Animal 4\n",
"])\n",
"\n",
"# Names of the marine animals\n",
"animal_names = [\"Shark\", \"Dolphin\", \"Whale\", \"Seal\"]\n",
"\n",
"print(\"Marine Animal Data Matrix:\")\n",
"print(data_matrix)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "da58a600",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "IRUi38YdzKyo",
"outputId": "049d7e18-7f92-41eb-fd6f-99082d3a4a59"
},
"outputs": [],
"source": [
"# Task 1: Calculate and print the maximum size of any marine animal.\n",
"\n",
"max_size = # your code here\n",
"print(f\"Maximum Size of any marine animal: {max_size} meters\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1d9a499c",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "359qQwAyzNfm",
"outputId": "fbb7fc39-b3a4-40a9-9d65-34bcecb5b393"
},
"outputs": [],
"source": [
"# Task 2: Calculate and print the average swimming speed across all marine animals.\n",
"\n",
"avg_speed = # your code here\n",
"print(f\"Average Swimming Speed of all marine animals: {avg_speed} km/h\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ea84eec5",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "drOQn2btzP01",
"outputId": "68d0bee2-f80e-49c0-ec21-34734f00b253"
},
"outputs": [],
"source": [
"# Task 3: Identify and print the name of the marine animal with the highest diet variety.\n",
"# The index of the max diet variety\n",
"max_diet_index = # your code here\n",
"\n",
"# Indentify the name of the animal using the found index\n",
"max_diet_animal = # your code here\n",
"print(\"Marine animal with the highest diet variety:\", max_diet_animal)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "ba7be9db",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "pf3NbijJzSDQ",
"outputId": "231ef25c-1ba5-4468-bfce-976751fc173e"
},
"outputs": [],
"source": [
"# Task 4: Identify and print the names of marine animals that have an average depth below 200 meters.\n",
"\n",
"shallow_animals = # your code here\n",
"print(\"Marine Animals with Average Depth Below 200 meters:\")\n",
"\n",
"# Print the names of the animals from animal_names using for loop\n",
"for i in shallow_animals:\n",
" print(animal_names[i])"
]
},
{
"cell_type": "markdown",
"id": "1c8ca27d",
"metadata": {
"id": "hTnb8r2PsjoB"
},
"source": [
"____\n",
"### **Exercise: Student performance analysis**\n",
"You have data on different students' performance in three courses: Intro2EE, Linear Circuit, and Digital Systems, during the first quarter. Each student is represented by a row, and their grades are recorded in columns. Your goal is to analyze this data by calculating and printing various statistics as indicated below:\n",
"\n",
"1. Calculate the average grade of each student in the first quarter and print the results.\n",
"2. Calculate the average grade in each course and print the results.\n",
"3. First, find the indices (row, column) of the maximum grade in `student_data` array and next print the name of the student who got that.\n",
"4. Identify and print the names of the students who failed the linear circuit course.\n",
"5. Identify and print the names of students with grades below the average in Intro2EE.\n",
"\n",
"Note that we are deliberately using a small array here so that you can check your results and validate them.\n",
"\n",
":::{tip}: In order to get the numbers to \"behave\" like integers, use the `astype(int)` operation.\n",
":::\n",
"\n",
":::{tip}: When using `np.mean()`, defining the axis is very important. axis=0 corresponds with rows and axis=1 corresponds with columns.\n",
":::\n",
"\n",
"Let's practice first."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "1adac541",
"metadata": {
"id": "WPtpztyDm969"
},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
"# a (5,4) matrix representing student grades\n",
"student_data = np.array([\n",
" [ \"Sara\", 8, 7, 6],\n",
" [ \"Ahmed\", 9, 5, 5],\n",
" [ \"Maria\", 7, 6, 8],\n",
" [ \"Finn\", 6, 4, 7],\n",
" [ \"Aisha\", 10, 9, 8]\n",
"])"
]
},
{
"cell_type": "markdown",
"id": "e776d65e",
"metadata": {
"id": "jJOHlciyzaY7"
},
"source": [
"#### **Before we start**\n",
"Since we have a mix of names and grades, Python saves all elements of the array as strings. However, we need to save them as numbers to be able to calculate the statistics.\n",
"\n",
"Therefore, a good practice to make things easier for us is to separate and save the grades in a new list and use that in our manipulations."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "57871728",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "eyVk79KvjXF_",
"outputId": "98c3b239-26e8-489b-bee5-40b3fccfae15"
},
"outputs": [],
"source": [
"# create an array only with names\n",
"names = # your code here\n",
"print ( names )\n",
"\n",
"# Remove the names from the matrix\n",
"grades = # Your code here\n",
"print(grades)"
]
},
{
"cell_type": "markdown",
"id": "2ed81e3f",
"metadata": {
"id": "VSD6FWAfnTPJ"
},
"source": [
"As you can see, they are all string so we have to change them to int or floats"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f956195a",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "5LprnRrCnb75",
"outputId": "2a74a9d6-8aaf-4387-ad1c-7bf2b02cb0d1"
},
"outputs": [],
"source": [
"grades = # your code here\n",
"print(grades)"
]
},
{
"cell_type": "markdown",
"id": "19327dad",
"metadata": {
"id": "10TtrMcPk14p"
},
"source": [
"Now we'll work on the tasks as described above."
]
},
{
"cell_type": "markdown",
"id": "2ee7897e",
"metadata": {
"id": "zwJn4kQ1cNsa"
},
"source": [
"#### **Task 1**"
]
},
{
"cell_type": "markdown",
"id": "de6b687a",
"metadata": {
"id": "SU78L7COnytb"
},
"source": [
"To find the average you can use `np.mean()`. However, it's important here to note that we want the average of all grades (different courses, for each student). That means we have to average along the columns (axis = 1). It's good practice to print the shape to also check that the number of averages matches the number of students."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "93476dee",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "svhFC8B4LT1J",
"outputId": "39958907-5f3f-4f29-b164-f0b78c0f8f76"
},
"outputs": [],
"source": [
"# Calculate the average grade for each student\n",
"average_student_grades = # your code here\n",
"print(average_student_grades)\n",
"print(average_student_grades.shape)"
]
},
{
"cell_type": "markdown",
"id": "f2e00ef1",
"metadata": {
"id": "DkxGSr9scYjT"
},
"source": [
"#### **Task 2**\n",
"Now calculate the average grade in each course and print the results, i.e., the average of all students."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "9fe410db",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "S2ButAjLTmoa",
"outputId": "c5b72fbe-166a-4bb8-f159-a822e6c06b4e"
},
"outputs": [],
"source": [
"# Calculate the average grade for courses\n",
"average_course_grades = # your code here\n",
"print(average_course_grades)"
]
},
{
"cell_type": "markdown",
"id": "27a8c789",
"metadata": {
"id": "Qb4FX3hVcyj9"
},
"source": [
"#### **Task 3**"
]
},
{
"cell_type": "markdown",
"id": "76891db3",
"metadata": {
"id": "tWhHh46Bdloz"
},
"source": [
"First, find the indices (row, column) of the maximum grade in `student_data` array and next print the name of the student who got that grade.\n",
"\n",
":::{tip}\n",
"When you find the index of the maximum value with `np.argmax()`, convert the flat index of the maximum value to a 2D index using `np.unravel_index(array_index, (shape))`.\n",
":::"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "2516dd38",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "Ozr9aUwbpzoL",
"outputId": "58f4c951-5d23-4206-b6ae-9fe8c95b2980"
},
"outputs": [],
"source": [
"# Task 3: Identify and print the student who achieved the highest grade\n",
"\n",
"# Find the index of the maximum value in the grades array\n",
"max_grade_index = # your code here\n",
"\n",
"# Convert the flat index of the maximum value to a 2D index\n",
"row, col = np.unravel_index(# your code here)\n",
"\n",
"# Print the index of the maximum value\n",
"print(row, col)"
]
},
{
"cell_type": "markdown",
"id": "ab1f53ef",
"metadata": {
"id": "sXf3lb_3qBQc"
},
"source": [
"To retrive the student's name we can use the first column in the initial `student_data` list and use the row index of the maximum value find above to print the name."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "4555cd18",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "7irt2C3EVnkU",
"outputId": "9f4ad87a-37d0-48d8-86f3-9b5a519d063c"
},
"outputs": [],
"source": [
"# Retrieve the student name from student_data using the found index\n",
"max_grade_student = # your code here #Same row of the max grade, and the first column\n",
"print (max_grade_student)"
]
},
{
"cell_type": "markdown",
"id": "7b744d95",
"metadata": {
"id": "Wz_XuYbuc6HJ"
},
"source": [
"#### **Task 4**\n",
"Identify and print the names of students who did not pass the Linear Circuit course. Note that LC grades are stored in the second column of the grade list, so we can use this list with the correct index and check if it's smaller than 6."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "411836e4",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "GXFgO3z334ii",
"outputId": "755ad11e-accc-454b-a968-b00ce570a443"
},
"outputs": [],
"source": [
"lc_fail = # your code here\n",
"print(lc_fail)"
]
},
{
"cell_type": "markdown",
"id": "b0e437e0",
"metadata": {
"id": "F0amFbgQ5IKV"
},
"source": [
"Note that as a result we get an array with \"True\" values for students (rows) with a failing grade. We can now use this to select those rows in other matrices."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "107cca28",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "aUCgJCCN34fc",
"outputId": "7b143d0c-0905-4cc8-d537-be8a43d0802e"
},
"outputs": [],
"source": [
"print(names[lc_fail])"
]
},
{
"cell_type": "markdown",
"id": "5d17dd97",
"metadata": {
"id": "fjTkg-ofdBX6"
},
"source": [
"#### **Task 5**\n",
"\n",
"Identify and print the names of students with grades below the average in Intro2EE."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "61f3902f",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "PlW-JbcYdEY_",
"outputId": "1e7f7c45-c3b7-45e7-96a2-7e333329ba47"
},
"outputs": [],
"source": [
"# Task 5: Identify and print the names of students with grades below the average in Intro2EE\n",
"\n",
"# Find all of the Intro2EE grades\n",
"I2EE_grades = # your code here\n",
"print(I2EE_grades)\n",
"\n",
"# Find the average\n",
"average_course_grade = # your code here\n",
"print(average_course_grade)\n",
"\n",
"# Find all of the students with grades below average\n",
"I2EE_below_average = # your code here\n",
"print(I2EE_below_average)\n",
"# Only the rows corresponding to \"True\" values in the boolean array are selected."
]
},
{
"cell_type": "markdown",
"id": "98d851e9",
"metadata": {
"id": "J7kgEc3R6vVg"
},
"source": [
"#### **Final remark**\n",
"\n",
"Note that as you get better in coding you can also join all the single commands above in a single line. This will help to make your code more compact and allows you to use fewer variables, but decreases the readibility of your code. Here is an example where we use one single line on only the initial array to complete task 5."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "a342c953",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "QXw8RaKq6tyo",
"outputId": "68821680-154d-4069-e2f7-30c7f6c97ce9"
},
"outputs": [],
"source": [
"# Task 5\n",
"I2EE_below_average = # your code here\n",
"print(I2EE_below_average)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "376c8ed6",
"metadata": {
"id": "CdQxSt_ZkFx9"
},
"outputs": [],
"source": []
}
],
"metadata": {
"jupytext": {
"text_representation": {
"extension": ".md",
"format_name": "myst",
"format_version": 0.13,
"jupytext_version": "1.16.4"
}
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.11"
},
"source_map": [
13,
19,
23,
27,
41,
52,
63,
74,
85,
96,
107,
118,
125,
142,
153,
157,
182,
211,
228,
236,
287,
306,
345,
350,
367,
377,
385,
393,
407,
429,
456,
482,
508,
521,
534,
550,
567,
589,
604,
611,
627,
631,
642,
646,
650,
654,
667,
672,
684,
688,
696,
715,
719,
731,
736,
747,
751,
761,
767,
791,
797,
811
]
},
"nbformat": 4,
"nbformat_minor": 5
}