import numpy as np """Numpy Arrays""" arr_1 = np.array([1, 2, 3, 4, 5]) # Create a numpy array from a list arr_2 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) # Create a 2D numpy array arr_1[2] = 99 # Modify an element in the array print("arr_1:", arr_1) # Output: [ 1 2 99 4 5] arr_2[1][2] = 111 # Modify an element in the 2D array print("arr_2:", arr_2) # Output: [[ 1 2 3] arr_2.shape = (1, 9) # Reshape the array to 1 row and 9 columns #Modern version of shape is arr_2.reshape(1, 9) arr_2 = arr_2.reshape(1, 9) #Reshape the array to 1 row and 9 columns print("arr_2:", arr_2) # Output: [[ 1 2 3 4 5 6 7 8 9]] """Data types in numpy arrays: https://numpy.org/doc/stable/user/basics.types.html""" # Create an array of type int8, this data type value range is from -128 to 127, if we try to create an array with values outside this range, it will wrap around and give us overflowed values arr_int8 = np.array([_ for _ in range(11, 100, 11)], dtype='int8') print("arr_int8 dataType:", arr_int8.dtype) # Output: int8 print("arr_int8:", arr_int8) # Output: [11 22 33 44 55 66 77 88 99] """Common Automatic Arrays""" ceros_1 = np.zeros(3) # Create an array of zeros with 5 elements print("ceros_1:", ceros_1) ceros_2 = np.zeros((2, 2)) # Create a 2D array of zeros with 3 rows and 4 columns print("ceros_2: \n", ceros_2) unos_1 = np.ones(5) # Create an array of ones with 5 elements print("unos_1: \n", unos_1) unos_2 = np.ones((4, 5)) # Create a 2D array of ones with 2 rows and 3 columns print("unos_2: \n", unos_2) identidad = np.identity(4) # Create a 4x4 identity matrix print("identidad: \n", identidad) eye_matrix = np.eye(3,4) # Create a 5x5 identity matrix, diferences between identity and eye is that eye can create non square matrices, while identity only creates square matrices print("eye_matrix: \n", eye_matrix, "\n") """----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------""" a = np.array([[1, 2, 3], [4, 5, 6]], dtype=np.int32) # Create a 2D array of int32 print("a: \n", a) ones_matrix = np.ones_like(a) # Create an array of ones with the same shape and data type as 'a' as a mask print("ones_matrix: \n", ones_matrix) steps_1 = np.arange(11, 100, 11) # Create an array of values from 0 to 10 with a step of 2 print("steps_1: \n", steps_1) steps_2 = np.arange(11, 100, 11).reshape((3, 3)) # Create a 2D array of values from 0 to 10 with a step of 2, and reshape it to 3 rows and 3 columns print("steps_2 dataType:", steps_2.dtype) print("steps_2: \n", steps_2) linealArray = np.linspace(0, 1, 10) # Create an array of 10 linearly spaced values between 0 and 1, an lineal array is an array that has values that are equally spaced between a start and end value, in this case we are creating an array of 10 values that are equally spaced between 0 and 1 print("linealArray dataType:", linealArray.dtype) # Output: float64, the default data type for linspace is float64, but we can specify a different data type if we want print("linealArray: \n", linealArray) randomArray = np.random.random(100) # Create an array of 100 random values between 0 and 1, the random function generates random values between 0 and 1 print("randomArray: \n", randomArray) print("randomArray dataType:", randomArray.dtype, "\n") """Properties and Attributes of Numpy Arrays""" arr_3 = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]], dtype=np.uint16) print("Array Properties") print("Dimensions:", arr_3.ndim) print("Shape:", arr_3.shape) print("Size:", arr_3.size) print("Data Type:", arr_3.dtype, "\n") """Math Operations on Numpy Arrays""" arr1 = np.array([10, 20, 30]) # Create an array of values from 1 to 30 with a step of 10 arr2 = np.array([1, 2, 3]) # Create an array of values from 1 to 3 print("arr1: \n", arr1) print("arr2: \n", arr2) print(f"Addition: {arr1} + {arr2} = {arr1 + arr2}") print(f"Multiplication: {arr1} * {arr2} = {arr1 * arr2}") print(f"Power: {arr1} ** {arr2} = {arr1 ** arr2}") print(f"Sine: sin({arr1}) = {np.sin(np.radians(arr2))}") arr3 = np.arange(1, 10).reshape((3, 3)) arr4 = np.arange(11, 100, 11).reshape((3, 3)) print("arr3: \n", arr3) print("arr4: \n", arr4) print(f"Addition: {arr3} + {arr4} = {arr3 + arr4}") print(f"Multiplication: {arr3} * {arr4} = {arr3 * arr4}") print(f"Power: {arr3} ** {arr4} = {arr3 ** arr4}") print(f"Cosine: cos({arr3}) = {np.cos(np.radians(arr4))} \n") #trigonometrics functions are defined in radians (argument) """Indexing and Slicing Numpy Arrays""" matrix = np.array([[10, 20, 30], [40, 50, 60], [70, 80, 90]]) print("matrix: \n", matrix) print(f"Element (1,2) of matrix: {matrix[1, 2]} \n") # Access the element at row 1, column 2 (0-based indexing) print(f"First row of matrix: {matrix[0, :]} \n") # Access the first row of the matrix print(f"All rows of the matrix: \n {matrix[:, :]} \n") # Access all rows and columns of the matrix print(f"Last column of the matrix: {matrix[:, 1]} \n") # Access the last column of the matrix print(f"First 2 rows and columns: \n {matrix[:2, :2]} \n") # Access the first 2 rows and first 2 columns of the matrix """Reshaping numpy arrays""" original = np.arange(12) reestructurado = original.reshape((3, 4)) # Reshape the original array to 3 rows and 4 columns (make a matrix of 3 rows and 4 columns) print("Original array: \n", original) print("Reshaped array: \n", reestructurado) print("transposed array: \n", reestructurado.T) # Transpose the reshaped array (swap rows and columns) """Stadistics and aggregation functions on numpy arrays (statistic topic)""" data = np.array([[1, 2], [3, 4]]) print(f"Sum of all elements: {np.sum(data)}") print(f"Mean of all elements: {np.mean(data)}") print(f"Standard deviation of all elements: {np.std(data)}") print(f"Variance of all elements: {np.var(data)}") print(f"Sum of each column: {np.sum(data, axis=0)}") # Sum along columns, indicated by axis were 0 is the first axis (columns) and 1 is the second axis (rows) in a 2D array, so when we specify axis=0, we are telling numpy to sum along the columns, which means that it will sum all the elements in each column and return an array with the sums of each column, while if we specify axis=1, we are telling numpy to sum along the rows, which means that it will sum all the elements in each row and return an array with the sums of each row. print(f"Sum of each row: {np.sum(data, axis=1)}") # Sum along rows print(f"Maximum value: {np.max(data)}, minimum value: {np.min(data)} \n") print(f"Sum of the first 2 rows and first column: {data[:2, 0].sum()}") # Sum of the first 2 rows and first column of the data array """Boolean masking with numpy arrays""" numbers = np.array([1, 15, 8, 20, 3 ,12]) print(f"Original array: \n {numbers}") greater_than_10 = numbers[numbers > 10] # Create a boolean mask for elements greater than 10 print(f"Boolean mask for elements greater than 10: \n {greater_than_10} \n") """More function of numpy arrays""" numbers.sort() # Sort the array in-place print("Order of the elements in the array: ", numbers) a = np.array([11, 22, 33, 44]) b = np.array([55, 66, 77, 88]) print(f"Concatenation of a and b: {np.concatenate((a, b))}") # Concatenate two arrays, tuples are required as argument a1 = np.array([[1, 1], [2, 2]]) a2 = np.array([[3, 4], [5, 6]]) print(f"Stacking a1 and a2 vertically: \n {np.vstack((a1, a2))}") # Stack arrays vertically (row-wise), tuples are required as argument print(f"Stacking a1 and a2 horizontally: \n {np.hstack((a1, a2))}") # Stack arrays horizontally (column-wise), tuples are required as a = np.array([11, 11, 22, 33, 44, 11, 55, 33, 44, 11, 99]) print(f"Unique elements in a: {np.unique(a)}") # Find unique elements in the array