El post abarca los básico para trabajar con estructura de datos del tipo tuplas, listas, diccionarios y conjuntos, a su vez construcción de loops (comprehensions) y funciones.
Disclaimer A: La información contenida en esta página está bajo una Licencia Creative Commons Atribución-NoComercial-SinDerivadas 4.0 Internacional y fue construida bajo mi rol como ayudante (Teacher Assistant) de la Catedra Business Intelligence para las Finanzas.
Disclaimer B: Este post está basado en mis propios resumenes a partir de los capítulos del libro Python for Data Analysis: Data Wrangling with Pandas, NumPy, and IPython, de Wes McKinney. La mayoría de los ejemplos provienen de momento del libro.
Advertencia: La página es un complemento a la cátedra y por nada la sustituye.
Una característica de Python como lenguaje de programción es su orentación a los objetos. Un objeto debe verse como un “caja” que puede contener números, string, funciones, clases, modulos, etc. Cada objeto está asociado a un tipo (type) y datos internos. Lo anterior hace que python sea un lenguaje muy flexible.
Cualquier texto que es precedido por el símbolo (#) es ignorado por el interpretador de Python. Esto se suele usar para comentarios.
# esto es un comentario sobre la linea
print("Hola Mundo")
Algunos programadores agregan el comentario en la linea del código.
print("Hola Mundo") # esto es un comentario en la linea
Lo bueno es que Python permite usar Multi-line (block) comments utilizando (’’’ o """).
'''
esto es un
multi-line
(block)
comment
'''
print("Hola Mundo")
Los objetos en Python tienen atributos y métodos.
Si creamos el objeto a:
a = 'foo'
Luego agregamos (.) y con Tab veremos los atributos, entre ellos capitalize, center, isupper, etc.
En python un módulo (module) es un archivo con extensión .py que contiene códigos, imaginemos que creamos el archivo modulo_ejemplo.py con lo siguiente:
Si queremos acceder a las variables y funciones definida en modulo_ejemplo.py, desde otro archivo .py que se encuentra en el mismo directorio, debemos escribir:
import modulo_ejemplo
result = modulo_ejemplo.f(5)
pi = modulo_ejemplo.PI
Es equivalente con usar:
from modulo_ejemplo import f, g, PI
result = g(5, PI)
Se puede usar la palabra as para importar el módulo o funciones con otros nombre para abreviar o convención:
import ejemplo_modulo as em
from ejemplo_modulo import PI as pi, g as gf
r1 = sm.f(pi)
r2 = gf(6, pi)
Lo anterior resume la lógica de usar librerías ubicadas en repositorios centralizados tales como pandas (pd), numpy (np), statsmodels (sm), matplotlib (plt), etc.
Para instalar librerías, es necesario saber que versión de Python se está utilizando, luego ir a la terminal (linea de comandos) del sistema operativo e instalar utilizando
pip install nombre_de_la_librería
Si se está utilizando el ambiente de Anaconda, deben abrir la terminal (linea de comandos) correspondiente a este ambiente e instalar la librería.
| Operador | Operacion | Ejemplo | Resultado |
|---|---|---|---|
| ** | Exponente | 2 ** 3 | 8 |
| % | Modulo | 22 % 8 | 6 |
| // | Division de integer | 22 // 8 | 2 |
| / | Division | 22 / 8 | 2.75 |
| * | Multiplicación | 3 * 5 | 15 |
| - | Resta o sustración | 5 - 2 | 3 |
| + | Adición o suma | 2 + 2 | 4 |
En Python el operador ** es evaluado primero, *, /, // y % son evaluado después. de izquierda a derecha; los operadores + y - son evalueados últimos (también de izquierda a derecha). Por ejemplo, si deseamos calcular: \[ (5 - 1) * ((7 + 1) / (3 - 1)) \] Escribimos en el script:
(5 - 1) * ((7 + 1) / (3 - 1))
16.0
La lógica es la siguiente:
\[ \begin{align} (5 - 1) & * ((7 + 1) / (3 - 1)) \\ 4 & * ((7 + 1) / (3 - 1)) \\ 4 & * (8 / (3 - 1)) \\ 4 & * (8 / 2) \\ 4 & * 4.0 \\ & 16.0 \end{align} \]
| Operador | Descripción |
|---|---|
a & b |
Verdadero si tanto a y b son verdadero, para integers, responde a Y |
a | b |
Verdadero si a o b es verdadero, para integers, responde a O |
a == b |
Verdadero si a es igual a b |
a != b |
Verdadero si a no es igual a b |
a <= b, a < b |
Verdadero si a es menor (menor o igual) a b |
a > b, a >= b |
Verdadero si a es mayor (mayor o igual) a b |
a is b |
Verdadero si a y b se refieren al mismo objeto de Python |
a is not b |
Verdadero si a y b se refieren a diferente objeto de Python |
| Tipos de Datos | Ejemplo |
|---|---|
| Integers (int) | -2 , -1 , 0 , 1 , 2 , 3 , 4 , 5 |
| Floating-point numbers (float) | -1.25 , -1.0 , ‐ -0.5 , 0.0 , 0.5 , 1.0 , 1.25 |
| Strings (str) | ‘a’ , ‘aa’ , ‘aaa’ , ‘Holaa!’ , ‘11 gatos’ |
| Boolean (bool) | Verdadero (TRUE) o False (FALSE) |
| None | El valor “null” de Python |
Los tipos númericos primarios para Python son los int y float. los int pueden almacenar arbitrariamente grandes números.
num_int = 12312551
# lo elevo al cuadrado
num_int**2
151598912127601
En el caso del tipo float, son valores de doble-precision (64-bit), que pueden ser expresados en notación cientifica.
float_num = 7.231
float_numscien = 6.78e-5
La división de dos int será un float (en Python 3.x).
type(5)
<class 'int'>
type(5/2)
<class 'float'>
Para escribir un string, basta con usar ("") o (’’):
b = "no todos lo que brilla es oro"
Es importate saber que los string son inmutables (no se pueden modificar). Muchos objetos de Python se pueden convertir a string usando la función str.
aa = 5.6
s = str(aa)
print(s)
5.6
type(s)
<class 'str'>
Son tan flexibles que podemos crear dos objetos del tipo string y “sumarlos”.
parte_a = "Where's the money Lebowski?, "
parte_b = "glugluglug..."
parte_a + parte_b
"Where's the money Lebowski?, glugluglug..."
Los dos valores que pueden tener los boolean en Python son True y False
True and True
True
False or True
True
str, bool, int y floatLos tipos str, bool, int y float son también funciones en Python.
s = '3.14159'
fval = float(s)
type(fval)
<class 'float'>
int(fval)
3
bool(fval) # todo número distinto a cero sera verdadero, es como si fuera 1
True
bool(0) # cero será falso
False
En construcción…
El statement for verifica si la condición es verdadera (True), entonces evalua el código que viene a continuación
x = 0
if x < 0:
print('Es negativo')
A un if puede seguir un elif y finalmente un else si todas las condiciones anteriores son falsas (False).
x = 0
if x < 0:
print('Es negativo')
elif x == 0:
print('Igual a cero')
elif 0 < x < 5:
print('Positivo pero menor a 5')
else:
print('Positivo y mayor o igual a 5')
Igual a cero
Si en el ejemplo x fuese negativo, ninguna elif será “alcanzado”. También se puede usar and y or:
a = 5; b = 7
c = 8; d = 4
if a < b or c > d:
print('logrado')
logrado
for loopslos for loops realizan un iteración sobre una colección como una lista o tupla (en la siguiente sección se presentan), la sintaxis es:
for value in collection:
# realiza algo sobre los valores
A continuación vamos a construir una lista que contendrá 5 valores, de los cuales, dos serán None:
secuencia = [1, 2, None, 4, None, 5]
Luego un objeto que tendrá el valor 0:
total = 0
Ahora se sumara los valores del objeto secuencia que no contengan None, para esto se utilizará un for loop y la opción continue:
for val in secuencia:
if val is None:
continue
total += val
Se debería obtener el valor de 12 en el objeto total:
total
12
Ahora se construirá una nueva secuencia donde se buscará su suma, pero hasta el valor 5:
secuencia_2 = [1, 2, 0, 4, 6, 5, 2, 1]
total_hasta_5 = 0
for val in secuencia_2:
if val == 5:
break
total_hasta_5 += val
A partir del objeto secuencia_2, si sumamos los valores hasta que sea igual a 5, deberíamos obtener el número 13.
total_hasta_5
13
Se debe tener en consideración que el uso de break, funcionara sobre el for más cercano, por ejemplo:
for i in range(4):
for j in range(4):
if j > i:
break
print((i, j))
(0, 0)
(1, 0)
(1, 1)
(2, 0)
(2, 1)
(2, 2)
(3, 0)
(3, 1)
(3, 2)
(3, 3)
Un while loop espcifica un condición que se cumplirá hasta que está sea falsa o bien cuando el loop especifique termine usando un break.
x = 256
total = 0
while x > 0:
if total > 500:
break
total += x
x = x // 2
print (total, x)
256 128
384 64
448 32
480 16
496 8
504 4
La función range, permite generar un interador tal como:
range(10)
range(0, 10)
list(range(10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Si quiero un iterador que parte vaya de 0 hasta 20 de 2 en 2, se puede usar:
list(range(0, 20, 2))
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Es importante notar que el valor final no es incluido.
seq = [1, 2, 3, 4]
for i in range(len(seq)):
print(seq[i])
1
2
3
4
Python presenta cuatros estructuras de datos: tuplas (tuples), listas (list), diccionarios (dict) y conjuntos (sets).
tup = 4, 5, 6
tupla_anidada = (4, 5, 6), (7, 8)
Podemos transformar un iterador por medio de la tuple:
tuple([4, 0, 2])
(4, 0, 2)
Inclusive un string:
tup_string = tuple('string')
tup_string
('s', 't', 'r', 'i', 'n', 'g')
Se puede acceder a los elementos de un objeto usando los brackets ([ ]), como C++ o Java, el índice parte del 0.
tup_string[0]
's'
Si bien una tupla no puede ser modificada, si está se compone por ejemplo de una lista, esta si se puede modificar:
tupla_muchos = tuple([1, 'hola', [1, 2], True])
tupla_muchos[2].append(3)
tupla_muchos
(1, 'hola', [1, 2, 3], True)
También se pueden sumar o multiplicar:
(4, None, 'hola') + (6, 0) + ('mundo',)
(4, None, 'hola', 6, 0, 'mundo')
('hola', 'mundo')*4
('hola', 'mundo', 'hola', 'mundo', 'hola', 'mundo', 'hola', 'mundo')
list.
una_list = [2, 3, 7, None]
una_tupla = ('hola', 'mundo', None)
tupla_a_lista = list(una_tupla)
tupla_a_lista
['hola', 'mundo', None]
Ahora como tupla_a_lista es una lista, podemos modificarla
tupla_a_lista[1] = 'se cambio'
tupla_a_lista
['hola', 'se cambio', None]
tupla_a_lista.append([1, 2, None])
tupla_a_lista
['hola', 'se cambio', None, [1, 2, None]]
Es una colección flexible de llave-valor (key-value), donde la llave son objetos de python. Para crearlos se utiliza curly braces ({ }).
dict_vacio = {}
dict_1 = {'a': 'algun valor', 'b': [1, 2, 3, 4]}
dict_1
{'a': 'algun valor', 'b': [1, 2, 3, 4]}
dict_1[7] = 'un int'
dict_1
{'a': 'algun valor', 'b': [1, 2, 3, 4], 7: 'un int'}
dict_1['b']
[1, 2, 3, 4]
Para verificar si un diccionario contiene cierta llave (key), se usa lo mismo que para un lista o tupla:
'b' in dict_1
True
Los conjuntos es una colección sin orden de elementos únicos. Se puede pensar como un diccionario pero solo con llaves y no con valores. Se pueden crear usando la función set o curly braces ({ })
set([2, 2, 2, 1, 3, 3])
{1, 2, 3}
{2, 2, 2, 1, 3, 3}
{1, 2, 3}
Los conjuntos soportan operaciones de conjuntos como unión, intesección, diferencia, etc. consideremos estos dos conjuntos:
a = {1, 2, 3, 4, 5}
b = {3, 4, 5, 6, 7, 8}
a.union(b)
{1, 2, 3, 4, 5, 6, 7, 8}
a | b # alternativamente
{1, 2, 3, 4, 5, 6, 7, 8}
a.intersection(b)
{3, 4, 5}
a & b # alternativamente
{3, 4, 5}
Una list comprehensions es una característica muy útil de Python, debido que permite resumir lineas de código (loops) en una linea (one liner). Estas se pueden aplicar a listas, conjuntos y diccionarios.
En una lista:
[expr for val in collection if condition]
Si quisieramos obtener el cuadrado desde 1 hasta 50, usando loops debería ser:
squares = []
for i in range(1, 51):
squares.append(i**2)
print(squares)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500]
usando una list comprehensions:
squares2 = [i**2 for i in range(1, 51)]
print(squares2)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500]
Otro ejemplo es obtener el producto cartesiano.
Si A y B son conjunto (sets), entonces el producto cartesiano es el conjunto de pares (a, b), donde ‘a’ está en A y ‘b’ está en B.
\[ A \times B = \{\ (a, b) \ |\ a \in A, \ b \in B \} \]
A = [1, 3, 5, 7]
B = [2, 4, 6, 8]
producto_cartesiano = [(a, b) for a in A for b in B]
print(producto_cartesiano)
[(1, 2), (1, 4), (1, 6), (1, 8), (3, 2), (3, 4), (3, 6), (3, 8), (5, 2), (5, 4), (5, 6), (5, 8), (7, 2), (7, 4), (7, 6), (7, 8)]
En un conjunto:
set_comp = {expr for value in collection if condition}
Por ejemplo:
strings = ['a', 'as', 'bat', 'car', 'dove', 'python']
unique_lengths = {len(x) for x in strings}
unique_lengths
{1, 2, 3, 4, 6}
En un diccionario:
dict_comp = {key-expr : value-expr for value in collection if condition}
Construimos una diccionario:
dictA = {
'platano' : 23,
'manzana' : 56,
'naranja' : 78,
'ciruela': 46
}
Luego se va a construir una lista pero con en mayúscula la primera letra:
dict_vacia = {}
for nombre, numero in dictA.items():
dict_vacia[nombre.capitalize()] = numero
dict_vacia
{'Platano': 23, 'Manzana': 56, 'Naranja': 78, 'Ciruela': 46}
Usando una dict comprehensions
{nombre.capitalize(): numero for nombre, numero in dictA.items()}
{'Platano': 23, 'Manzana': 56, 'Naranja': 78, 'Ciruela': 46}
Una función es un grupo de condiciones relacionadas que cumplen con una tarea específica. La sintaxis es:
def function_name(parameters):
"""docstring"""
statement(s)
Para obtener \(n^2\) de cualquier número:
def elevado(n):
return n**2
elevado(1)
1
elevado(2)
4
elevado(4)
16
Básicamente una función anónima, es una función que nunca se define (def) y basta para utilizar una vez y no sistemáticamente:
seqC = [1, 2, 4]
def apply_a_una_lista(lista, f):
return [f(x) for x in lista]
apply_a_una_lista(seqC, lambda x: x ** 2)
[1, 4, 16]
Construya la siguiente secuencia de números incluyendo los None: 1, 2, None, 4, 5, 6, None. Luego utilizando un loop sume los elemenos que son númericos (no considerar None).
Construya la siguiente secuencia de números: 1, 2, 3, 4, 5, 6, 7. Luego utilizando un loop sume los elemenos menores al número 5.
Sume todo los números desde 0 hasta 99.999 que sean múltiplos de 3 o 5.
Construya una función que para un número n entregue como output la suma de los cuadrados de \(1^2 + 2^2 + 3^2 + 4^2 + ... + n^2\).
Contruya una función que entregue como output si un número es o no divisible por 2.
Construya una función que entregue la media aritmética o media geométrica de un conjunto de datos.
Genere la siguiente matriz:
\[ A = \begin{pmatrix} 3 & 0 & 2 \\ 2 & 0 & 2 \\ 0 & 1 & 1 \end{pmatrix} \]
Encuentre la transpuesta de la matriz A.
Encuentre la matriz inversa de A.
Genere las siguientes matrices:
\[ B = \begin{pmatrix} 2 & 4 \\ 5 & -6 \end{pmatrix} \hskip 1em \text{y} \hskip 1em C = \begin{pmatrix} 9 & -3 \\ 3 & 6 \end{pmatrix} \]
Obtenga la suma de B + C.
Obtenga el producto punto entre B y C.
Utilizando un loop, genera una lista que almacene los valores de la tercera columna de la matriz A.
Use matrices para resolver los siguientes sistemas de ecuaciones:
\[ \begin{aligned} a + b + c & = 6 \\ 3a - 2b + c & = 2 \\ 2a + b - c & = 1 \end{aligned} \]
\[ \begin{aligned} 3a + 4b - 5c + d & = 10 \\ 2a + 2b + 2c - d & = 5 \\ a - b + 5c - 5d & = 7 \\ 5a + d & = 4 \end{aligned} \]
El estimador MCO minimiza la suma de los errores de predicción al cuadrado, \(\sum^{n}_{i=1}(Y_{i} - \beta_{0}X_{1i} - ... - \beta_{k}X_{ki})^2\). La fórmula del estimador MCO se obtiene tomando la derivada de la suma de los errores de predicción al cuadrado respecto de cada elemento del vector de coeficientes, igualando estas derivadas a cero y resolviendo para el estimador \(\hat{\beta}\), se obtiene:
\[ \mathbf{\hat{\beta}} = (\mathbf{X'X})^{-1}\mathbf{X'Y} \]
Utilizando la librería Pandas, importe la base de datos , la que Consiste en el presupuesto gastado en publicidad (TV, radio, newspaper) de 200 productos.
Utilizando Numpy obtenga \(\mathbf{\hat{\beta}}\) de la siguiente regresión:
\[ Sales_{i} = \beta_{0} + \beta_{1}TV_{i} + \varepsilon_{i} \]