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)