MDCIPROPE2026/sesion2_3/numpy_introduction.py

163 lines
7.7 KiB
Python

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