MLDS1 - primer sesion

Machine Learning

Ejecutar comandos desde jupyther notebooks

%%writefile ejemplo.txt
Hola a todos
!cat ejemplo.txt
!cat /etc/os-release
!lscpu

Montar drive

from google.colab import drive
drive.mount('/content/drive')
https://github.com/OneDrive/onedrive-sdk-python

Diferencias entre listas y tuplas

Las listas con corchete ([]) son mutables, es decir podemos modificar sus valores

lista = [2, 3, 5]
lista
lista[0] = "Hola"
lista

Las tuplas contiene elementos y esta lista es inmutable (())

tupla = (3, 6, 50)
print(tupla[0])

Note que la siguiente modificacion genera un error ya que la tupla es inmutable

tupla[0] = "hola"

Cuando una función retorna varios elementos, Python devuelve una tupla de esos elementos

def retorna_varios_elementos():
  return "hola", "a todos"
type(retorna_varios_elementos())
def retorna_varios_elementos():
  return "hola", 5
retorna_varios_elementos()
type(retorna_varios_elementos())
lista = list(retorna_varios_elementos())
lista[0] = 3
lista

Cualquier lista o tupla puede ser desempaquetada

a, b, c = [0,4,3] # el igual funciona como una función de desempaquetado
print(a,b,c)
a, *b = (0,4,3) # star operator de python
print(a,b)

Si una función retorna varios elementos en forma de tupla, los podemos desempaquetar con ayuda de la igualdad

x, y = retorna_varios_elementos() # desempaquetar
x
y
print(x, y)
def retorna_varios_elementos():
  return "hola", 5, 34
retorna_varios_elementos()
def retorna_varios_elementos():
  return "hola", 5, 34, 98, 100

El guion funciona como un elemento descartable

a, _, _, b, _ = retorna_varios_elementos()
a
b

Funciones con argumentos

Puedo crear una función que acepte varios valores

def funcion(c):
  print(type(c))
  print(c)
funcion(2)
funcion(3, 3, 2, 2)

En el caso de querer tener una función que me acepte 0 o varios elementos, utilizaremos el operador estrella (star operator)

def funcion(*c):
  print(type(c))
  print(c)

funcion()
funcion(3)
funcion(3, 3, 2, 2, 5)

Podemos tener argumentos que son obligatorios, y otros que son opcionales

def funcion(ele1, ele2, *resto_de_elementos):
  print(f"ele1 = {ele1}") # esto se conoce como un f-string
  print(f"ele2 = {ele2}")
  print(f"resto_de_elementos = {resto_de_elementos}")

Una función que no retorna nada, por defecto retorna un objeto de tipo NoneType

valor_retornado = funcion(3)
print(type(valor_retornado))
valor_retornado = funcion(3.333, 5)
print(type(valor_retornado))
funcion(3, 5, 8, 9, 3)

Operador Zip

El operador zip o cremallera nos permite juntar dos arreglos elemento a elemento

lista_1 = ["Alejandro", "Daniela", "Diego", "Pedro", "Armando"]
lista_2 = [6, 58, 7, 8, 1]
list(zip(lista_1, lista_2))

# zip = [('Alejandro', 6), ('Daniela', 58), ('Diego', 7), ('Pedro', 8), ('Armando', 1)]
for x in zip(lista_1, lista_2):
  print(type(x))
  print(x)

Si recuerdan yo puedo desempaquetar tuplas

# zip = [('Alejandro', 6), ('Daniela', 58), ('Diego', 7), ('Pedro', 8), ('Armando', 1)]
for nombre, edad in zip(lista_1, lista_2): # desempaquetamos tuplas
  print("nombre = ", nombre, " edad = ", edad)
  print("nombre = %s edad %s" % (nombre, edad))
  print(f"tipo nombre = {type(nombre)}, tipo edad = {type(edad)}")
  print(f"nombre = {nombre}, edad = {edad}")
# zip = [(4,6),(58,58),(7,7),(5,8),(1,1)]
for x, _ in zip(lista_1, lista_2): # Puedo desempaquetar y descartar alguno elementos
  print(type(x))
  print(x)
a, _ = [43, 2] # Desempaquetar obviando un valor
a
lista_2
import numpy as np
arreglo_2 = np.array(lista_2)
list(zip(lista_1, arreglo_2[[3,0,1,4,2]], lista_2, lista_2))

Listas por comprension

print(range(10))

El siguiente ejemplo muestra un for normal

lista = []
for i in range(10):
  lista.append(i * i)
print(lista)

El siguiente ejemplo muestra una lista por comprensión

print([i*i for i in range(10)]) # Listas por comprensión
print(tuple((i*i for i in range(10)))) # tuplas por comprensión
print({i for i in range(10)}) # conjuntos por comprensión
print({str(i):i for i in range(10)}) # diccionarios por comprensión

Listas

lista = list(range(20))
print(lista)
lista = lista[:-1] # remove el último valor de la lista
print(lista)
lista[::-1]
lista.remove(9)
print(lista)

La siguiente instrucción me permite definir una lista por comprensión con un if anidado

lista = list(range(20))
print([x for x in lista if x != 9])
lista = list(range(20))
print([x for x in lista if x%2==0])
lista = list(range(20))
print([(x, x*x,x**3,x**(1/2)) for x in lista if x%2==0])

La primera parte de un filtro recibe una función. Esta función debe devolver un valor booleano

def par(x):
  return x%2 == 0
list(filter(par, lista))
lista2 = [3,5,8,9,2,0]
list(filter(par, lista2))
list(zip(lista_1, lista_2))[3][1]

Explicación de conjuntos

lista1 = ["joseph", "alejandro", "daniela", "andrea", "steve", "joseph"]
lista2 = ["alejandro", "steve", "pepe", "pepe"]

Queremos obtener un listado sin repeticiones de elementos de la lista 1

print(set(lista1)) # set es conjunto en inglés

Podriamos hacer lo mismo, pero con la lista dos

print(set(lista2))

Que elementos son únicos de la lista1 que no estan en la lista2

print(set(lista1) - set(lista2))
print(set(lista1))
print(set(lista2))
print(set(lista1).union(set(lista2)))
print(set(lista1))
print(set(lista2))
print(set(lista1).intersection(set(lista2)))
for elemento in set(lista1).intersection(set(lista2)):
  print(elemento)
lista = list(set(lista1).intersection(set(lista2)))
lista.sort()
lista

Obtener elementos repetidos de una lista

from collections import Counter

lista = Counter(lista1).items()
print(lista)
[elemento for elemento in lista if elemento[1] > 1]

Funciones como argumentos y Lambda functions

Definamos primero una función con nombre llamada funcion_suma

def funcion_suma(a, b):
  return a + b
funcion_suma(5, 10)
def funcion_multiplicacion(a, b):
  return a * b
funcion_multiplicacion(5, 10)

A continuación definimos una función que recibe otra función como argumento

def funcion_todera(funcion_a_aplicar, numero_1, numero_2):
  return funcion_a_aplicar(numero_1, numero_2)
funcion_todera(funcion_suma, 10, 2 ) # función como argumento
funcion_todera(funcion_multiplicacion, 10, 2)
funcion_todera(lambda x,y : x+y, 10, 2) # función sin nombre, o función lambda
funcion_todera( lambda x,y : x*y, 10, 2)
funcion_todera(lambda x,y : x/y, 10, 2)
def funcion_todera(funcion_a_aplicar, *operadores):
  return funcion_a_aplicar(operadores)
funcion_todera(lambda x : sum(x), 3, 5, 1)
lista = list(range(10))
lista
def elevar_cubo(x):
  return x ** 3

La función map sirve para iterar sobre una lista de datos y aplicar una función a cada dato de la lista

list(map(elevar_cubo, lista))
list(map(elevar_cubo, np.array(range(10))))

Cuando el arreglo es un arreglo bidimensional de python, ya no funciona

list(map(elevar_cubo, np.ones((5,5))))
list(map(lambda x: x**6, lista))
pseudo_diccionario = [["nombre", "Joseph"], ["nombre", "Joseph"], ["nombre", "Joseph"]]
list(map(lambda x: print(x[0], " ", x[1]),  pseudo_diccionario))
lista=[4,8,10]
list(map(lambda x: x-2, lista))
matriz_1
list(map(elevar_cubo, matriz_1))
list(range(9))

La primera operación de un filtro debe devolver un booleano

list(filter(lambda x: x>3, list(range(9))))
lista = np.arange(10)
lista
lista[lista>3]
list(filter(lambda x: print(x), {"a": 3, "b": 6}.items()))
list(filter(lambda x: x[1]>3, {"a": 3, "b": 6}.items()))

Descargar archivos desde drive

Gdown -> descarga de archivos desde drive

!gdown --id 1aUi2r9_abPE8wV3Hf-WWdaWtsVCXw8ca

Operadores ternarios

variable_1 = 20
if variable_1 > 40:
  print("mayor a 40")
else:
  print("menor a 40")
variable_1 = 20
print("mayor") if variable_1 > 40 else print("menor")
cadena = "mayor" if variable_1 > 40 else "menor"
cadena

Comprensión de listas

list(range(10))
list(range(3, 10))
list(range(3, 10, 2))
lista = []
for i in range(10):
  print(i)
lista = []
for i in range(10):
  lista.append(i)

lista
np.array(lista)
lista = [variable **3 for variable in range(10)]
lista
lista_1 = np.array(range(9)).reshape((3,3))
lista_2 = np.array(range(9)).reshape((3,3))*2
for x, y  in zip(lista_1.ravel(), lista_2.ravel()):
  print("x", x)
  print("y",y)
lista_1
lista_2
lista_1.ravel()

Filter

lista = [3, 4, 5, 6]
def menoresACuatro(x):
  return x<=4

list(filter(menoresACuatro, lista))
list(filter(lambda x: x<=4, lista)) # la función del filter siempre debe ser un booleano
edades = [38, 45, 22, 10]
def filtrar_edades(edad):
  return edad <= 25
edades_filtradas = []
for edad in edades:
  persona_aceptada = filtrar_edades(edad) # función de dedición
  if(persona_aceptada): # dedición
    edades_filtradas.append(edad) # agregamos el elemento que cumple la condición

print(edades_filtradas)
list(filter(filtrar_edades, edades))
list(filter(lambda edad: edad < 25, edades))

Funciones

def suma(a, b):
  return a + b
type(suma(4, 3)) # Desempaquetamiento
def suma_y_resta(a, b):
  return a + b, a - b
suma_y_resta(3, 5)
type(suma_y_resta(3, 5))
def suma_y_resta(a, b):
  return (a + b, a - b)
variable = suma_y_resta(3, 5)
variable[0] = 3
def suma_y_resta(a, b):
  return [a + b, a - b]
print(type(suma_y_resta(3, 5)))

Map and Reduce

edades = [38, 45, 22, 10]
def extraer_decadas(edad):
  return int(edad / 10)
lista_de_decadas = []
for edad in edades:
  decadas = extraer_decadas(edad)
  lista_de_decadas.append(decadas)
print(lista_de_decadas)
[int(edad / 10) for edad in edades]
list(map(extraer_decadas, edades))
list(map(lambda edad: int(edad / 10), edades))
lista = [5, 6, 3, 2, 3]
def cuadrado(x):
  return x*x
l = []
for elemento in lista:
    l.append(cuadrado(elemento))

print(l)
list(map(cuadrado, lista))
list(map(lambda x: x*x, lista))
print(list(map(lambda x: x*x, [23,5,3,265])))
print(list(map(lambda x: x*x, (23,5,3,265))))
print(list(map(lambda x: x*x, {23,5,3,265})))
for elemento in {23,5,3,265,334}:
  print(elemento)
5 in [3,5,3,2]
dir([3,5,3,2])
[3,5,3,2].index(5)
print(list(map(lambda item: print(item), {43: 23, 32:5})))
def cuadrado(x):

  x = x -3
  x = x*5
  x = x /2
  return x*x

list(map(cuadrado, lista))
import pandas as pd
df = pd.DataFrame([{"name": "hola", "apellido": "pepe"}])
df.apply()
def suma(x, y):
  return x*y

Reduce

#@markdown * **Ejecute esta celda para instalar _Python Tutor_.**
!pip3 -q install tutormagic
%load_ext tutormagic
edades = [38,45,22, 10]
def funcion_suma(suma_parcial, nuevo_dato):
  return suma_parcial + nuevo_dato
%%tutor -s -h 500

edades = [38,45,22, 10]

def funcion_suma(suma_parcial, nuevo_dato):
  return suma_parcial + nuevo_dato

suma = 0
for edad in edades:
  suma = funcion_suma(suma, edad)

print(suma)
import functools
functools.reduce(funcion_suma, edades)
%%tutor -s -h 500
edades = [38,45,22, 10]

def funcion_multiplicacion(multiplicacion_parcial, nuevo_dato):
  return multiplicacion_parcial * nuevo_dato

multiplicacion = 1
for edad in edades:
  multiplicacion = funcion_multiplicacion(multiplicacion, edad)

print(multiplicacion)
import functools
functools.reduce(funcion_multiplicacion, edades)

Funciones como argumentos

def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

def multiplicacion(num1, num2):
  return num1 * num2

def division(num1, num2):
  return num1 / num2

def elevacion(num1, num2):
  return num1 ** num2

#print(suma(multiplicacion, division, 5, 43))

#print(suma(division, multiplicacion, 5, 43))

print(suma(elevacion, multiplicacion, 5, 43))

def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2, 4) + fun2(num1, num2)

def multiplicacion(num1, num2):
  return num1 * num2

def division(num1, num2):
  return num1 / num2

suma(multiplicacion, division, 5, 43) # No se puede ya que la función 1, que le
                                      # enviamos como multiplicacion solo acepta 2 parametros,
                                      # en este caso nos genera error de posiciones de argumentos

Funciones Lambda

def fun(x):
  return x+1
fun(3)
lambda x: x+1
(lambda x: x+1)(3)

Vamos a cambiar las funciones normales de python, por sus respectivas funciones lambda, y vamos a ver en el camino como se utilizan estas funciones.

def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

def multiplicacion(num1, num2):
  return num1 * num2

def division(num1, num2):
  return num1 / num2

suma(multiplicacion, division, 5, 43)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

multiplicacion = lambda num1, num2: num1 * num2

def division(num1, num2):
  return num1 / num2

suma(multiplicacion, division, 5, 43)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

multiplicacion = lambda num1, num2: num1 * num2

division = lambda num1, num2: num1 / num2

suma(multiplicacion, division, 5, 43)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

division = lambda num1, num2: num1 / num2

suma(lambda num1, num2: num1 * num2, division, 5, 43)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

suma(lambda num1, num2: num1 * num2, lambda num1, num2: num1 / num2, 5, 43)
suma = lambda fun1, fun2, num1, num2 : fun1(num1, num2) + fun2(num1, num2)

suma(lambda num1, num2: num1 * num2, lambda num1, num2: num1 / num2, 5, 43)
[3.5 , 5 , 6 ].apply(lambda x: x+1)

Is vs ==

print('Operador is')
a = 1.0
b = 1
c = 1
lista1 = [1,2,3]
lista2 = [1,2,3]
print(a is b) # No tienen el mismo tipo de dato y por lo tanto son objetos distintos.
print(a == b) # Contienen el mismo valor al verificar su igualdad.
print(b is c) #¿en este caso b y c ocupan el mismo lugar de memoria?***
tupla1 = (1,2,3)
tupla2 = (1,2,3)
print(tupla1 is tupla2) #¿Por qué en este caso son diferentes?***
print(tupla1 == tupla2) #¿Por qué en este caso son diferentes?***
print(lista1 is lista2)
print(lista1 == lista2)

Generador

#@markdown * **Ejecute esta celda para instalar _Python Tutor_.**
!pip3 -q install tutormagic
%load_ext tutormagic
%%tutor -s -h 500

def funcion():
  yield 1
  yield 2
  yield 3


generador = funcion()
print(next(generador))
print(next(generador))
print(next(generador))
%%tutor -s -h 500

def funcion():
  yield [[2]]
  yield [[3]]
  yield [[]]


generador = funcion()
print(next(generador))
print(next(generador))
print(next(generador))
%%tutor -s -h 500

def funcion_parcial(dato):
  def funcion(elemento):
    return dato + elemento

  return funcion

def funcion():
  yield funcion_parcial(0)
  yield funcion_parcial(1)
  yield funcion_parcial(2)


generador = funcion()
print(next(generador)(1))
print(next(generador)(1))
print(next(generador)(1))
generador = funcion()
print(next(generador))
generador = funcion()
print(generador.__next__())
print(generador.__next__())
print(generador.__next__())
print(generador.__next__()) # no hay mas yield
generador = (i*i for i in range(10)) # tuplas por comprensión
print(generador.__next__())
print(generador.__next__())
print(generador.__next__())
print(generador.__next__())
print(generador.__next__())
print(generador.__next__())
def funcion(n):
  for i in range(n):
    yield i
generador = funcion(10)
generador.__next__()
import itertools
generador = (i*i for i in range(10)) # tuplas por comprensión
generador, copia_generador = itertools.tee(generador)
generador.__next__()
copia_generador.__next__()
generador.__iter__()
generador.__next__()

Numpy

Explicación de Numpy

import numpy as np
np.ones((10,6))
np.ones((10,6)) + 6
np.zeros((10,6)) + 6
matriz = np.zeros((10,6))
matriz.fill(6)
matriz
np.full((10,6), 6)
np.full((10,6,5, 10), 6).shape
list(range(20))
arreglo = np.array(range(20))
arreglo
np.arange(20)
np.arange(-3, 20, 0.3)
np.linspace(0, 20, num=5) # genera 100 números entre 0 y 20 igualmente distribuidos
np.linspace?
np.linspace(0, 20, num=5, endpoint = False) # genera 100 números entre 0 y 20 igualmente distribuidos
arreglo = np.arange(20)
arreglo
arreglo.shape

Siempre nos devuelve una tupla en la que cada dato de la tupla corresponde a una dimensión del arreglo

arreglo.reshape((4, 5))
arreglo.reshape((4, 5)).reshape((2,2,5))
matriz = arreglo.reshape((2,10))
matriz
matriz[0, 3]
matriz[1, 6]
matriz[:, 2: 6]
tensor = arreglo.reshape((2,2,5))
tensor
tensor[0, 1, 3]

Indexado elegante

matriz = arreglo.reshape((4, 5))
matriz
matriz[:, [1, 3]]
matriz[1:3, [1, 3]]
matriz
matriz[[0,1], :] = matriz[[1,0],:] # Indexado elegante
matriz
5 % 2
5 - 5 // 2 * 2
matriz % 2
matriz_impar = (matriz % 2).astype(bool)
matriz_impar == True
matriz_impar = (matriz % 2).astype(str)
matriz_impar
matriz_impar[matriz_impar == "1"] = "impar"
matriz_impar[matriz_impar == "0"] = "par"
matriz_impar
~(matriz % 2).astype(bool)
matriz[(matriz % 2).astype(bool)]
matriz[(matriz % 2 == 0).astype(bool)]
matriz[(matriz % 2).astype(bool) == False]
arreglo.reshape((2, -1))
arreglo.reshape((3, -1))
arreglo.reshape((2, 2, 5))
troceado = arreglo[0:18] # troceado de listas
cubo = troceado.reshape((2,3,3))
cubo
cubo.ravel?
cubo.flatten()
cubo.flatten?
matriz = np.arange(20).reshape((4,5))
#display(matriz)
print(matriz)
print(matriz.shape)

Ravel

matriz.ravel()

Squeeze

agregar_dimension = arreglo.reshape((4, 1, -1))
agregar_dimension.shape
agregar_dimension
np.squeeze(agregar_dimension, axis=1)
np.squeeze(agregar_dimension, axis=1).shape

Operaciones matriz

matriz
matriz[1,2]
matriz[1, 2] = 999
matriz
matriz[:,:]
matriz[0,:]
matriz[0, :] = [10,20,30,40,50]
matriz
matriz[:,0]
matriz_1 = matriz[:,0][:, np.newaxis]
matriz_1
matriz_1.shape
matriz[:,0].shape
matriz_2 = matriz[:,0][np.newaxis, :]
matriz_2
matriz_2.shape
matriz[:,0].reshape((1,4))
matriz[:,0].reshape((1,4)).shape
matriz = matriz.reshape((5, -1))
matriz
matriz.dtype
matriz2 = np.zeros((6, 4))
matriz2[:5, :] = matriz
matriz2[5,: ] = matriz2[4, :] * 4
matriz2
matriz2.dtype
matriz
media = matriz.mean(axis=0)
media[np.newaxis, : ]
np.vstack((matriz, media[np.newaxis,: ]))

matriz[:,0].reshape((1, 4))
matriz[0:2,:]
%timeit sum(range(1_000_000_000)) # timeit es un magico de jupyter
%timeit np.arange(0,1_000_000_000,1).sum() # implementación en lenguaje C
matriz.sum(axis=1) #Sume por columnas
matriz.sum(axis=0) #Sume por filas
matriz[:, 3:]
matriz[:, :3]
matriz[0, :] = 3
matriz
matriz[:, 1:3] = matriz[:, 1:3] * 3
matriz
for i in range(matriz.shape[0]):
  matriz[i, i] = 6
matriz
np.eye(4)
np.ones((4,4))
arreglo = np.ones((4,4))
arreglo + np.eye(4)
tensor = np.ones((4,5,3))
#display(tensor)
print(tensor)
tensor[3,:,:] = tensor[3,:,:] * 4
tensor
tensor[3,:,:].shape
(tensor[1,:,:] * 4 ).shape
slice_tensor = tensor[1,:,:] * 4
slice_tensor
tensor
tensor[::3,:,:]
matriz_1 = np.ones((4,4)) * 6
matriz_1
matriz_2 = np.ones((4,4)) * 2.5
matriz_2
matriz_1 * matriz_2
np.ones(3) * np.ones(4) # dotwise
np.dot(matriz_1, matriz_2).flatten()
matriz_1 @ matriz_2
[0,1,2,3,4,5,6,7,8,9,10]
list(range(11))
lista = []
#[]
for i in range(11):
  lista.append(i)

lista
[x**2 for x in range(11)]
[2 for y in range(11)]
[i for i in range(5,11,2)]
lista_inicial = list(range(16))
arreglo_inicial = np.array(lista_inicial)
arreglo_inicial.reshape((4,4))
matriz_1 = np.array(list(range(16))).reshape((4,4))
display(matriz_1)
matriz_2 = np.array(range(16)).reshape((4,4)) * 2
display(matriz_2)
#np.array(list(range(16))).reshape((4,5))
matriz_1 * matriz_2
np.dot(matriz_1, matriz_2)
matriz_2.sum()
matriz_2.sum(axis=0)
matriz_2.sum(axis=1)

Suma por eje

matriz = np.array([[3,8,9], [10,15,3], [2,7,6]])
matriz
matriz.sum()
matriz.sum(axis=0)
matriz.sum(axis=1)

Shape de matrices de numpy

matriz = np.ones((3,4))
type(matriz.shape)
M , N = matriz.shape
print(M, N)

Desviación estandar

import numpy as np
arreglo = np.array([3, 5, 6, 2])
arreglo
arreglo.shape
np.sqrt(((arreglo - arreglo.mean())**2).sum()/arreglo.shape[0])
arreglo.std()
matriz = np.array([[3, 5, 6, 2], [5,2,3,32]])
matriz
matriz.shape
matriz.std(axis=0)
matriz.std(axis=1)
matriz_ravel = matriz.ravel()
matriz_ravel
desviacion_estandar = np.sqrt(((matriz_ravel - matriz_ravel.mean())**2).sum()/matriz_ravel.shape[0])
desviacion_estandar
matriz.std()
media = matriz.mean()
media
tensor = np.array([[[3,4],[5,2]],[[6,2],[7,6]]])
tensor
tensor.shape

1 - Pais (colombia, chile, ecuador) 2 - deportes (natacion, baloncesto, futbol) 3 - personas

estatura = np.random.uniform(50, 275, size=(3, 3, 10))
estatura
estatura.std(axis=2)
estatura.std(axis=(1, 2))
estatura.std(axis=(0, 2))
estatura.std()
np.std(estatura)

EJemplo de uso de tensores

Normalmente en deep learning se trabaja con arreglos de multiples dimensiones com el siguiente.

Deep Learning -> arreglos (batch_size, número_filas, número_columnas, filtro)

tensor = np.random.uniform(0, 1, size=(5,5,5))
tensor
tensor[0, 4, 3]

Ayuda

np.array?
help(np.array)
help(np.squeeze)

Range

range(10000000000000000000000000000000000) # lazy operation - una operación peresoza
list(range(10)) # range es un generador de python
list(range(3, 10)) # range es un generador de python
list(range(3, 10, 2)) # range es un generador de python

Listas por comprension

print(range(10))
lista = []
for i in range(10):
  lista.append(i * i)
print(lista)
print([i*i for i in range(10)])
lista = []
for i in range(10):
  if i % 2 == 0:
    lista.append(i * i)
print(lista)
print([i*i for i in range(10) if i % 2 == 0])
print([[i, ((i*i)+3)/2] for i in range(10)])

Tuplas

tupla = (2, 5, 8)
tupla[-1] = 9
lista = list(tupla)
lista[-1] = 9
lista

Diccionario por comprensión

diccionario = {i:j for i,j in zip(range(10), range(10))}
diccionario
paises = ["bogota", "medellin", "cali"]
poblacion = [10, 6, 3]
diccionario = {ciudad: poblacion for ciudad,poblacion in zip(paises, poblacion)}
diccionario
list(zip(paises, poblacion))

Funciones como argumentos

def suma(num1, num2):
  return num1 + num2
suma(3, 5)
def operacion(fun, num1, num2):
  return fun(num1, num2)
operacion(suma, 3, 5)
def multiplicacion(num1, num2):
  return num1 * num2
operacion(multiplicacion, 3, 5)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

def multiplicacion(num1, num2):
  return num1 * num2

def division(num1, num2):
  return num1 / num2

def elevacion(num1, num2):
  return num1 ** num2

#print(suma(multiplicacion, division, 5, 43))

#print(suma(division, multiplicacion, 5, 43))

print(suma(elevacion, multiplicacion, 5, 43))

def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2, 4) + fun2(num1, num2)

def multiplicacion(num1, num2):
  return num1 * num2

def division(num1, num2):
  return num1 / num2

suma(multiplicacion, division, 5, 43) # No se puede ya que la función 1, que le
                                      # enviamos como multiplicacion solo acepta 2 parametros,
                                      # en este caso nos genera error de posiciones de argumentos

Funciones Lambda

def fun(x):
  return x+1
fun(3)
lambda x: x+1
(lambda x: x+1)(3)
def operacion(fun, num1, num2):
  return fun(num1, num2)
type(operacion)
operacion(lambda x,y: x+y, 3, 5)
operacion(lambda x,y: x/y, 10, 2)
operacion(lambda x,y: (x+5) ** (y+2), 10, 5)
operacion(lambda x,y: [x**2, y**2, x**2+y**2], 10, 5)
operacion(lambda x,y: [x**2,
                       x+232 * y,
                       y**2,
                       x**2+y**2], 10, 5)

Vamos a cambiar las funciones normales de python, por sus respectivas funciones lambda, y vamos a ver en el camino como se utilizan estas funciones.

def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

def multiplicacion(num1, num2):
  return num1 * num2

def division(num1, num2):
  return num1 / num2

suma(multiplicacion, division, 5, 43)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

multiplicacion = lambda num1, num2: num1 * num2

def division(num1, num2):
  return num1 / num2

suma(multiplicacion, division, 5, 43)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

multiplicacion = lambda num1, num2: num1 * num2

division = lambda num1, num2: num1 / num2

suma(multiplicacion, division, 5, 43)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

division = lambda num1, num2: num1 / num2

suma(lambda num1, num2: num1 * num2, division, 5, 43)
def suma(fun1, fun2, num1, num2):
  return fun1(num1, num2) + fun2(num1, num2)

suma(lambda num1, num2: num1 * num2, lambda num1, num2: num1 / num2, 5, 43)
suma = lambda fun1, fun2, num1, num2 : fun1(num1, num2) + fun2(num1, num2)

suma(lambda num1, num2: num1 * num2, lambda num1, num2: num1 / num2, 5, 43)
[3.5 , 5 , 6 ].apply(lambda x: x+1)

Is vs ==

print('Operador is')
a = 1.1 # esto es un decimal
b = 1   # esto es un entero
c = 1
d = 1.0
print(a is b) # No tienen el mismo tipo de dato y por lo tanto son objetos distintos.
print(a == b) # Contienen el mismo valor al verificar su igualdad.
print(b is c) #¿en este caso b y c ocupan el mismo lugar de memoria?***
tupla1 = (1,2,3)
tupla2 = (1,2,3)
print(tupla1 is tupla2) #¿Por qué en este caso son diferentes?***
print(tupla1 == tupla2) #¿Por qué en este caso son diferentes?***
lista1 = [1,2,3]
lista2 = [1,2,3]
print(lista1 is lista2)
print(lista1 == lista2)

Listas de Python y arreglos de numpy

lista = [23, "andrés", (1,3),  True, ["pedro", {"clave":"valor"}]]
lista
import numpy as np # recuerden que el as es como un alias que se le pone a la libreria
arreglo = np.array([23, "andrés", (1,3),  True, ["pedro", {"clave":"valor"}]])
arreglo
arreglo + 1
arreglo2 = np.array([3, 5, 1, 7])
arreglo2.dtype
arreglo2 + 1
lista_de_ciudades = np.array(["bogota", "medellin", "cali", "cartagena"])
lista_de_ciudades.dtype

Datos no tipados en Python

dato = 3
dato + 3
dato = "hola"
dato + "."
arreglo = np.array([2, 4, 7])
arreglo + 1
arreglo.dtype
arreglo[-1] = "hola"
arreglo = np.array([2, 4, 7], dtype=object)
arreglo.dtype
arreglo[-1] = "hola"
arreglo
arreglo + 1

Conexión a drive

Operaciones con bits

binario1 = 0b1
binario2 = 0b1
binario1 ^ binario2

Map

pedidos = [5, 6, 3, 2, 3]
lista = [0,0,0,0,0]
variable = 3
lista[variable] = 1
lista
for pedido in pedidos:
  print(pedido)
def cuadrado(x):
  return x*x
list(range(5))
n = int(input())
l = []
for elemento in range(n):
  l.append(cuadrado(elemento))

l
l = []
for elemento in lista:
    l.append(cuadrado(elemento))

print(l)
list(map(cuadrado, lista))
list(map(lambda x: x*x, lista))
print(list(map(lambda x: x*x, [23,5,3,265])))
print(list(map(lambda x: x*x, (23,5,3,265))))
print(list(map(lambda x: x*x, {23,5,3,265})))
for elemento in {23,5,3,265,334}:
  print(elemento)
5 in [3,5,3,2]
dir([3,5,3,2])
[3,5,3,2].index(5)
print(list(map(lambda item: print(item), {43: 23, 32:5})))
def cuadrado(x):

  x = x -3
  x = x*5
  x = x /2
  return x*x

list(map(cuadrado, lista))
import pandas as pd
df = pd.DataFrame([{"name": "hola", "apellido": "pepe"}])
df.apply()
def suma(x, y):
  return x*y
import functools
functools.reduce(suma, lista)

This website is copyright 2023 All Shaman