Manual Python Básico
Manual Python Básico
DEL PERÚ
Enero, 2020
PROGRAMACIÓN EN PYTHON
Nivel Básico
Índice
1. Acerca de Python 6
1.1. ¿Qué es Python? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2. Características de Python . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3. Breve historia de Python . . . . . . . . . . . . . . . . . . . . . . . . . . 7
3. Identificadores de Python 24
3.1. Reglas para escribir identificadores . . . . . . . . . . . . . . . . . . . . . 24
3.2. Algunas consideraciones . . . . . . . . . . . . . . . . . . . . . . . . . . 24
4. Operadores 25
4.1. ¿Qué son los operadores? . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2. Operadores aritméticos . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.3. Operadores de comparación (relacionales) . . . . . . . . . . . . . . . . . 26
4.4. Operadores lógicos (booleanos) . . . . . . . . . . . . . . . . . . . . . . 27
4.5. Operadores de Asignación . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6. Operadores Especiales . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
4.6.1. Operador de identidad . . . . . . . . . . . . . . . . . . . . . . . 28
4.6.2. Operador de Membresía . . . . . . . . . . . . . . . . . . . . . . 28
5. Tipos de Datos 30
5.1. Indexación . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
5.2. Números . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
5.3. Secuencias . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.3.1. Cadenas (Strings) . . . . . . . . . . . . . . . . . . . . . . . . . 32
5.3.2. Lista . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35
5.3.3. Tupla . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
5.4. Conjuntos (Set) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40
5.5. Diccionario . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
5.6. Conversión entre tipos de datos . . . . . . . . . . . . . . . . . . . . . . 42
6. Entrada y Salida 43
6.1. Función Input . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
6.2. Entrada de archivos: importación . . . . . . . . . . . . . . . . . . . . . 43
6.3. Salida usando la función print() . . . . . . . . . . . . . . . . . . . . . 44
6.4. Salida de archivos: exportación . . . . . . . . . . . . . . . . . . . . . . 46
8. Sentencias de Control 50
8.1. Sentencias selectivas: If, If-Else y If-Elif-Else . . . . . . . . . . . . . . . 50
8.1.1. Sentencia Selectiva if . . . . . . . . . . . . . . . . . . . . . . . 50
8.1.2. Sentencia Selectiva if...else . . . . . . . . . . . . . . . . . . . . 50
8.1.3. Sentencia if...elif...else . . . . . . . . . . . . . . . . . . . . . . . 51
8.1.4. Sentencias if anidadas . . . . . . . . . . . . . . . . . . . . . . . 51
8.1.5. Operador ternary . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.2. Sentencias iterativas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
8.2.1. Sentencia Iterativa for . . . . . . . . . . . . . . . . . . . . . . . 53
8.2.2. Sentencia Iterativa while . . . . . . . . . . . . . . . . . . . . . . 54
9. Funciones 56
9.1. ¿Qué es una función en Python? . . . . . . . . . . . . . . . . . . . . . 56
9.2. Tipos de funciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
9.2.1. Función convencional . . . . . . . . . . . . . . . . . . . . . . . 56
9.2.2. ¿Cómo llamar a una función? . . . . . . . . . . . . . . . . . . . 57
9.2.3. La sentencia return . . . . . . . . . . . . . . . . . . . . . . . . 57
9.2.4. Tipos de argumentos de una función . . . . . . . . . . . . . . . 58
9.2.5. Funciones Lambda . . . . . . . . . . . . . . . . . . . . . . . . . 60
9.3. Docstring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
9.4. Ámbito y vida útil de las variables . . . . . . . . . . . . . . . . . . . . . 61
9.5. Almacenamiento de sus funciones en Módulos . . . . . . . . . . . . . . 62
10.Clases y objetos 63
10.0.1. ¿Qué es un Objeto? . . . . . . . . . . . . . . . . . . . . . . . . 63
10.0.2. ¿Qué es una Clase? . . . . . . . . . . . . . . . . . . . . . . . . 63
11.Paquetes 65
11.1. ¿Qué son los paquetes? . . . . . . . . . . . . . . . . . . . . . . . . . . 65
11.2. El Stack Científico . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
11.3. ¿Qué son los módulos en Python? . . . . . . . . . . . . . . . . . . . . . 67
11.4. ¿Cómo importar módulos en Python? . . . . . . . . . . . . . . . . . . . 67
11.5. Sentencia import . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
11.6. Importar con cambio de nombre . . . . . . . . . . . . . . . . . . . . . . 68
11.7. Sentencia from ... import ... . . . . . . . . . . . . . . . . . . . . . . . . 69
11.8. Importar todas las funciones . . . . . . . . . . . . . . . . . . . . . . . . 69
11.9. Búsqueda de módulo de Python . . . . . . . . . . . . . . . . . . . . . . 70
11.10.Recargando un módulo . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
11.11.La función intertna dir() . . . . . . . . . . . . . . . . . . . . . . . . . 71
12.Librería Numpy 73
12.1. ¿Qué es Numpy? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
12.2. ¿Cómo puedo crear un array? . . . . . . . . . . . . . . . . . . . . . . . 73
12.3. Combinar array y tipos de datos en NumPy . . . . . . . . . . . . . . . . 76
12.4. Operaciones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77
12.5. Broadcasting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
13.Pandas 84
13.1. ¿Qué es Pandas? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
13.2. Series . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 84
13.2.1. Creación e indexación de Series . . . . . . . . . . . . . . . . . . 85
13.2.2. Tamaño, forma y conteo de valores . . . . . . . . . . . . . . . . 88
13.2.3. Alineación mediante etiquetas de índice . . . . . . . . . . . . . . 89
13.3. El DataFrame . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 90
13.3.1. Creación de un DataFrame . . . . . . . . . . . . . . . . . . . . 90
13.3.2. Selección de columnas de un DataFrame . . . . . . . . . . . . . 93
13.3.3. Selección de filas de un DataFrame mediante el índice . . . . . . 94
13.3.4. Selección de líneas mediante la selección Boolean . . . . . . . . . 97
13.3.5. Aritmética en un DataFrame . . . . . . . . . . . . . . . . . . . 98
13.4. Reindexación de los objetos Series y DataFrame . . . . . . . . . . . . 99
13.5. Manipulación de DataFrame aplicado a Finanzas. . . . . . . . . . . . . . 103
13.5.1. Reorganización y reestructuración de datos . . . . . . . . . . . . 104
13.5.2. Agrupación y agregación . . . . . . . . . . . . . . . . . . . . . . 115
14.Matplotlib 122
14.1. Introducción . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122
14.2. Pyplot . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
14.3. Multiples figuras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 124
14.4. Elementos del gráfico . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
14.4.1. Texto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
14.4.2. Cuadrícula . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
14.4.3. Leyenda . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
14.5. Tipos de gráficos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 132
14.5.1. Gráficos de líneas . . . . . . . . . . . . . . . . . . . . . . . . . 132
14.5.2. Gráficos de líneas con pandas . . . . . . . . . . . . . . . . . . . 134
14.5.3. Histogramas . . . . . . . . . . . . . . . . . . . . . . . . . . . . 135
14.5.4. Gráficos de barras . . . . . . . . . . . . . . . . . . . . . . . . . 136
14.5.5. Gráficos de barras horizontales . . . . . . . . . . . . . . . . . . 138
14.5.6. Gráficos de barras multiseries con Dataframe de pandas . . . . . 140
14.5.7. Gráficos de barras apiladas de multiseries . . . . . . . . . . . . . 141
14.5.8. Gráficos de barras apilados con un Dataframe de pandas . . . . . 142
14.5.9. Otras Representaciones de Gráficos de Barras . . . . . . . . . . . 143
14.5.10.Gráficos de Pie . . . . . . . . . . . . . . . . . . . . . . . . . . . 144
14.5.11.Gráficos de tarta con un Dataframe de pandas . . . . . . . . . . 147
14.5.12.Gráficos avanzados: Polares . . . . . . . . . . . . . . . . . . . . 147
14.6. Gráficos 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
14.6.1. Superficies 3D . . . . . . . . . . . . . . . . . . . . . . . . . . . 149
14.6.2. Gráficos de barras en 3D . . . . . . . . . . . . . . . . . . . . . . 150
14.7. Gráficos Multi-Panel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
14.7.1. Visualizar subplots dentro de otras subplots . . . . . . . . . . . . 151
1. Acerca de Python
1.1. ¿Qué es Python?
Python es un lenguaje de programa-
ción multiplataforma (es decir, se eje-
cuta en múltiples plataformas como
Windows, Mac OS X, Linux, Unix e
incluso se ha adaptado a las máqui-
nas virtuales Java y .NET.)
Python está disponible para todos los
principales sistemas operativos, como
Windows, Linux / Unix, OS / 2 y
Mac. Es un lenguaje fácil de apren-
der y entender, la mayoría de las libre-
rías/módulos y herramientas disponi-
bles son de código abierto y general-
mente vienen con licencias libres.
La mejora continua del lenguaje Pyt-
hon ha sido posible gracias a un gru-
po de personas dedicadas y compro-
metidas a apoyar la causa de propor-
cionar el servicio.
Páginas web
Juego de azar
El análisis científico
Python
applications
Numpy, Pandas,
Django Kivi Scions Scipy, Matplotlib, Numpy.lib.financial,
statsmodels pandas_datareader,
yahoo-finance,
Python_finance,
finance, economics.
1. Spyder
2. Jupyter Notebook
3. Jupyter Lab
5. Emacs
6. Vim
7. Gedit
8. Idle
Paso 1: ir a https://docs.anaconda.com/anaconda/install/hashes/win-3-64/
-Seleccionar “Just Me”, si solo quieren que se instale para su usuario de Windows.
- Clic en “Install”.
- Clic en Next.
- Clic en “Finish”.
1. Modo inmediato
Ejecución desde el
intérprete
En la parte inferior izquierda del panel de control hay una lista de carpetas
(y archivos) del directorio predeterminado. Puede navegar a la carpeta
donde desea almacenar su trabajo, o crear una carpeta nueva, haciendo
clic en el botón Nuevo situado en la parte superior derecha del panel y
seleccionando Carpeta. Finalmente, para crear un nuevo cuaderno Jupy-
ter, vaya al menú desplegable Nuevo en el lado derecho de la página y
seleccione Python 3.
Cuaderno Jupyter
∗ Los cuadernos Jupyter son aplicaciones web que se ejecutan local-
mente y que contienen código Pyhton, código LaTeX y texto Mark-
down. El lenguaje estándar es Python, sin embargo, tenga en cuenta
que una variedad de alternativas son compatibles, como por ejemplo
R.
∗ Un cuaderno Jupyter será más fácil de entender si incluye anotacio-
nes que expliquen lo que está ejecutando en el cuaderno. Además de
registrar las entradas y salidas de los cálculos, los cuadernos Jupyter
permiten al usuario insertar encabezados, notas explicativas, expre-
siones matemáticas e imágenes.
c) Modo JupyterLab
JupyterLab es un entorno de desarrollo interactivo basado en la web para
código y datos Jupyter. Si bien JupyterLab permite el uso de cuadernos
Jupyter, va más allá del clásico Jupyter Notebook al proporcionar una
aplicación web flexible y extensible con un conjunto de componentes
reutilizables.
∗ JupyterLab es flexible: se debe configurar y organizar la interfaz de
usuario para soportar una amplia gama de flujos de trabajo en ciencia
de datos, computación científica y Matching Learning.
∗ JupyterLab es extensible y modular: escriba plugins que añadan nue-
vos componentes e integren con los ya existentes.
Para mostrar la ruta del directorio actual del ordenador, se puede utilizar el código:
In [2]: %pwd
Out[2]: ’/Users/Yessenia’
Para crear una carpeta dentro de su directorio de documentos, escriba el código %ls
para listar los archivos y directorios en su directorio raíz, luego escriba %mkdir
programas y se creará esta nueva carpeta en su directorio. Finalmente, para validar
que se ha creado la nueva carperta, ejecute %ls.
In [7]: %cd ~
/Users/pine
In [8]: %ls
Applications/ Library/ Pictures/
Desktop/ Movies/ Public/
Documents/ Music/
Downloads/ News/
In [10]: %ls
Applications/ Library/ Pictures/
Desktop/ Movies/ Public/
Documents/ Music/ programs/
Downloads/ News/
Para limpiar el terminal IPython escriba el comando %clear o cls, lo que le dará
una nueva ventana del interprete.
2.4. Pyflakes
Una forma de evitar errores es utilizar un verificador de sintaxis. Afortunadamente,
el IDE de Spyder incluye un verificador de sintaxis, denominado Pyflakes que se
ejecuta en segundo plano cuando se está editando un programa Python usando
Spyder. Si hay un error en su código, Pyflakes marca el error.
El Editor Spyder, proporciona resaltado de sintaxis, que codifica palabras clave, co-
mentarios y otras características de la sintaxis de Python de acuerdo a su función, y
por lo tanto facilita la lectura del código y la detección de errores de programación.
El Editor ortográfico también proporciona la comprobación de la sintaxis, como un
corrector ortográfico en un programa de procesamiento de textos, que identifica
muchos errores de codificación. Esto puede acelerar enormemente el proceso de
codificación.
4
Es un documento guía de estilo para Pyhton, que no es de seguimiento obligatorio, pero es altamente
recomendable. Puede encontrar mayor información en: https://www.python.org/dev/peps/pep-0008/
3. Identificadores de Python
Un identificador es el nombre asignado a entidades como clase, funciones, variables,
etc; ayudando a diferenciar una entidad de otra.
4. Operadores
4.1. ¿Qué son los operadores?
Los operadores son símbolos especiales en Python que realizan cálculos aritméticos
o lógicos.
Por ejemplo:
>>> 2+3
5
# Output: x == y es False
x==y
# Output: x != y es True
x!=y
En muchos casos la ejecución de un bloque depende del valor real de más de una
sentencia. En estos casos, los operadores " and " ( " & ") y " or " ( "|") acuden
en nuestro rescate. La primera (’and’) se utiliza cuando la salida es ’verdadera’,
cuando ambas condiciones son ’verdaderas’. La segunda (’or’) se utiliza si la salida
es ’verdadera’, si alguna de las condiciones es ’verdadera’.
Ejemplo: Operadores Lógicos
x = True
y = False
# Output: x or y is True
x or y
# Output: False
x1 is not y1
# Output: True
x2 is y2
# Output: False
x3 is y3
# Output: True
’H’ in x
# Output: True
’hello’ not in x
# Output: True
1 in y
# Output: False
’a’ in y
5. Tipos de Datos
Python permite al usuario manipular variables para almacenar valores, y cada valor
en Python tiene un tipo de dato (no necesitan ser declaros) .
Los objetos en Python tienen identidad, un tipo y un valor (dado por el usuario
/ o un valor por defecto). La identidad, en Python, se refiere a la dirección y no
cambia. El tipo de dato puede ser cualquiera de los siguientes.
a) Cadenas (string)
b) Tuplas (tuples)
c) Listas (list)
a) Conjuntos
b) Diccionarios
5.1. Indexación
En Python el operador de indice[] permite acceder a un elemento de una
secuencia.
El índice del elemento al que se desea acceder debe ser un número entero.
Cada objeto almacenado en una secuencia tiene un número de índice asociado po-
sitivo, cero indexado y que comienza desde la izquierda, y el negativo que comienza
en -1 desde la derecha.
5.2. Números
La categoría numérica está compuesta por los números enteros, los números de
punto flotante y los números complejos. Se definen las clases int, float y
complex en Python.
La función type() permite consultar a qué tipo de dato pertenece una variable
o un valor; y la función isinstance() para verificar si un objeto pertenece a un
tipo de dato en particular.
a = 5
type(a)
b = 2.0
type(b)
c = 1+2j
isinstance(c,complex)
Un numero entero pueden ser de cualquier longitud, solo está limitado por la
memoria disponible.
Los enteros y punto flotante están separados por puntos decimales. 1 es entero,
1.0 es numero de punto flotante.
Python llama a cualquier número con punto decimal: un número de punto flo-
tante. Este término se utiliza en la mayoría de los lenguajes de programación, y
se refiere al hecho de que un punto decimal puede aparecer en cualquier posición
de un número. Este tipo de dato es exacto hasta 15 decimales.
Ejemplos.
a = 1234567890123456789
a
1234567890123456789
b = 0.1234567890123456789
b
0.12345678901234568
c = 1+2j
c
(1+2j)
5.3. Secuencias
5.3.1. Cadenas (Strings)
En Python una cadena es un objeto predefinido que contiene una serie de carac-
teres.
Se usa comillas simples o dobles para representar cadenas. Las cadenas de varias
líneas se pueden denotar mediante comillas triples, ”’ o """.
s = "Esto es una cadena"
s = ’’’una
multilinea’’’
"This is a string."
’This is also a string.’
Se puede crear una variable que contenga como valor un dato del tipo cadena,
usando el operador de asignación igual (=). Por ejemplo:
name = ’Harsh’
3*name
"HarshHarshHarsh"
Python puede buscar espacios en blanco adicionales en los lados derecho e izquierdo
de una string. Para asegurarse de que no existe ningún espacio en blanco en el
extremo derecho de una string, utilice el método rstrip().
>>> favorite_language = ’python ’
>>> favorite_language
’python ’
>>> favorite_language.rstrip()
’python’
>>> favorite_language
’python ’
También puede eliminar los espacios en blanco del lado izquierdo de una cadena
utilizando el método lstrip() o eliminar los espacios en blanco de ambos lados a la
vez utilizando strip():
>>> favorite_language = ’ python ’
>>> favorite_language.rstrip()
’ python’
>>> favorite_language.lstrip()
’python ’
>>> favorite_language.strip()
’python’
Cortar una cadena: se refiere a quitar alguna parte de la cadena. Por ejemplo:
>>>name = ’Sonam’
>>>name
’Sonam’
Para extraer la parte después de la primera letra, o después de las dos primeras
letras podemos escribir:
>>> name1=name[1:]
>>> name1
’onam’
>>>name = name[2:]
>>>name
’nam’
# s[4] = ’o’
print("s[4] = ", s[4])
# s[6:11] = ’world’
print("s[6:11] = ", s[6:11])
# Generación de error
# Las cadena son immutables en Python
s[5] =’d’
Evitando Errores de Tipo con la Función str(): Python sabe que la variable
podría representar el valor numérico 23 o los caracteres 2 y 3. Cuando usas núme-
ros enteros dentro de strings como esta, necesitas especificar explícitamente que
quieres que Python use el número entero como una string de caracteres. Puede
hacer esto envolviendo la variable en la función str(), que le dice a Python que
represente valores que no sean strings como strings. Ejemplo:
age = 23
message = "Happy " + str(age) + "rd Birthday!"
print(message)
5.3.2. Lista
Una lista es una secuencia ordenada de elementos. Es uno de los tipos de datos
más utilizados en Python y es muy flexible. No es necesario que todos los elementos
de una lista sean del mismo tipo.
Declarar una lista es bastante sencillo. Los elementos separados por comas se
incluyen entre corchetes [].
>>> a = [1, 2.2, ’python’]
∗ Una lista puede ser una colección de elementos homogéneos, por ejemplo:
[1, 2, 3].
∗ Puede contener diferentes elementos (heterogéneos), por ejemplo: [1, "abc,"
2.4].
∗ Una lista puede estar vacía []
∗ Finalmente una lista también puede contener una lista.
Por ejemplo.
a = [5,10,15,20,25,30,35,40]
# a[2] = 15
print("a[2] = ", a[2])
Las listas son mutables, esto es, el valor de los elementos de una lista puede
modificarse.
>>> a = [1,2,3]
>>> a[2]=4
>>> a
[1, 2, 4]
motorcycles[0] = ’ducati’
print(motorcycles)
Añadir elementos a una lista: Es posible agregar un nuevo elemento a una lista
usando la función append(). Al añadir un elemento a una lista, el nuevo elemento
se añade al final de la lista.
motorcycles = [’honda’, ’yamaha’, ’suzuki’]
motorcycles.append(’ducati’)
print(motorcycles)
del motorcycles[0]
print(motorcycles)
popped_motorcycle = motorcycles.pop()
print(motorcycles)
print(popped_motorcycle)
La salida muestra que el valor del último elemento fue eliminado del final de la
lista y ahora está almacenado en la variable popped_motorcycle.
[’honda’, ’yamaha’]
suzuki
Puede utilizar pop() para eliminar un elemento de una lista en cualquier posición
incluyendo entre paréntesis el índice del elemento que desea eliminar.
motorcycles = [’honda’, ’yamaha’, ’suzuki’]
first_owned = motorcycles.pop(0)
Si no conoces la posición del valor que quieres eliminar de una lista, puede utilizar
el método remove(). Esta función elimina sólo la primera aparición del valor
especificado.
motorcycles = [’honda’, ’yamaha’, ’suzuki’, ’ducati’]
too_expensive = ’ducati’
motorcycles.remove(too_expensive)
5.3.3. Tupla
Una tupla es una secuencia ordenada de elementos como en una lista. La única
diferencia es que las tuplas son inmutables, esto es, una vez creadas no pueden
ser modificadas.
Las tuplas se utilizan para proteger los datos contra la escritura y suelen ser más
rápidas que las listas, ya que no pueden cambiarse dinámicamente.
Se define entre paréntesis () donde los elementos están separados por comas.
>>> t = (5, ’programa’, 1+3j)
tup3
(1, 2, 3, 4)
Por Ejemplo:
num1= 2
num2= 3
Output
Tales construcciones pueden ser útiles para hacer tablas y otras estructuras. Se
puede acceder a los distintos elementos de una lista con una extensión directa del
esquema de indexación que hemos estado utilizando.
Ejemplos:
Las tuplas multidimensionales funcionan exactamente igual que las listas mul-
tidimensionales, excepto que son inmutables.
5.5. Diccionario
Un diccionario es una colección desordenada de pares clave-valor.
Generalmente se usa cuando tenemos una gran cantidad de datos. Los diccionarios
están optimizados para recuperar datos. Debemos conocer la clave para recuperar
el valor.
Un par clave-valor es un conjunto de valores asociados entre sí. Cada valor está
conectado a su valor por dos puntos, y los pares clave-valor individuales están
separados por comas.
6. Entrada y Salida
Python proporciona 2 formas de entrada: desde el teclado de la computadora y
el archivo de datos de entrada, asimismo hay dos formas de salida: la pantalla de
ordenador y el archivo de datos de salida. Se revisará cada una de estas formas de
entrada y salida.
num
’10’
float(’10’)
10.0
donde:
∗ objects es el (los) valor(es) a imprimir.
∗ separador sep se utiliza entre los valores. Por defecto se convierte en un
carácter de espacio.
∗ Una vez impresos todos los valores, se imprime end. Esto por default establece
una nueva línea.
∗ file es el objeto donde se imprimen los valores y su valor predeterminado
es sys.stdout (pantalla).
Ejemplo:
print(’This sentence is output to the screen’)
# Output: This sentence is output to the screen
a = 5
print(’The value of a is’, a)
# Output: The value of a is 5
print(1,2,3,4,sep=’*’)
# Output: 1*2*3*4
print(1,2,3,4,sep=’#’,end=’&’)
# Output: 1#2#3#4&
Incluso podemos usar argumentos de palabras clave para dar formato a la cadena.
print(’Hola {name}, {greeting}’.format(greeting = ’Buenos dias’, name = ’Miguel’))
Hola Miguel, Buenos dias
Incluso podemos dar formato a cadenas como el viejo estilo sprintf() usado en
el lenguaje de programación C. Usamos el operador % para lograr esto.
x = 12.3456789
print(’El valor de x es %3.2f’ %x)
El valor de x es 12.35
Donde,
así también
colors = [’red’,
’blue’,
’green’]
Podemos colocar varias declaraciones en una sola línea usando punto y coma (;)
a = 1; b = 2; c = 3
7.2. Indentación
En programación, indentación significa mover un bloque de texto hacia la dere-
cha insertando espacios o tabuladores, para así separarlo del margen izquierdo y
distinguirlo mejor del texto adyacente; en el ámbito de la imprenta, este concepto
siempre se ha denominado sangrado o sangría.
Un bloque de código (cuerpo de una función, bucle, etc.) comienza con una sangría
y termina con la primera línea sin sangrar. La cantidad de sangría depende del
programador, sin embargo, debe ser consistente en todo el bloque.
y
if True: print(’Hola’); a = 5
ambos son válidos y hacen lo mismo; sin embargo, el primer estilo es más claro.
En Python se usa el símbolo hash (#) para iniciar a escribir un comentario, lo que
escriba despues de una marca hash en su código, es ignorada por el intérprete de
Python.
Ejemplo:
# Este es un comentario
# Impresión de Hola
print(’Hola’)
Estas comillas triples se utilizan generalmente para cadenas de varias líneas, asi
como para comentarios de varias líneas. A menos que no sean docstrings, no
generan ningún código adicional.
""" Este es tambien un
ejemplo perfecto de
comentarios multi-línea"""
7.3.2. Docstring
Docstring es la abreviatura de cadena de documentación.
8. Sentencias de Control
8.1. Sentencias selectivas: If, If-Else y If-Elif-Else
Las sentencias selectivas forman parte integral de la programación, para la toma
de decisiones. Python reconoce un bloque de programación a través de la indentación.
La Indentación decide el comienzo y el final de un bloque en Python. Por lo tanto, es
importante tener cuidado con la Indentación, de lo contrario se obtendra un error en la
salida del código.
La sentencia if <condition> es seguida por dos puntos.
Ejemplo
# Si el numero es positivo, se imprime el mensaje apropiado
num = 3
if num > 0:
print(num, "es un numero positivo.")
print("Esto se imprime siempre.")
num = -1
if num > 0:
print(num, "es un numero positivo.")
print("Esto también se imprime siempre.")
Ejemplo.
# Programa que verifica que el numero es positivo o negativo
# Y muestra un mensaje apropiado
num = 3
if num >= 0:
print("Numero Positivo o Cero")
else:
print("Numero Negativo")
Sintaxis
if expresion_de_prueba1:
sentencia(s)1
elif expresion_de_prueba2:
sentencia(s)2
else:
sentencia(s)3
Ejemplo: Encuentre el mayor de los tres números digitados por el usuario, utilizando
un operador ternary.
# Operador Ternary
a = int(input(’Ingresa el primer número\t:’))
b = int(input(’Ingresar el segundo número \t:’))
c = int(input(’Enter the third number\t:’))
Looping significa repitiendo una serie de declaraciones hasta que una condición
sea verdadera.
Por ejemplo
# Programa que encuentra la suma de todos los numeros en una lista
# Lista de numeros
numeros = [6, 5, 3, 8, 4, 2, 5, 4, 11]
La función range()
Ejemplo 1.
# Output: range(0, 10)
print(range(10))
# Output: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(list(range(10)))
# Output: [2, 3, 4, 5, 6, 7]
print(list(range(2, 8)))
Ejemplo 2.
# Programa para iterar a través de una lista usando indexación
Por ejemplo.
digits = [0, 1, 5]
for i in digits:
print(i)
else:
print("No quedan items.")
Por ejemplo.
# Programa que suma los números naturales del 1 al n
# sum = 1+2+3+...+n
# A ser ingresado por el usuario. n = int(input("Ingrese n: "))
n = 10
# inicializa sum y el contador
sum = 0
i = 1
while i <= n:
sum = sum + i
i = i+1 # actualiza el contador
# imprime la suma
print("La suma es ", sum)
Output.
Ingrese n: 10
La suma es 55
Por Ejemplo.
# Ejemplo para ilustrar
# el uso de la sentencia else
# con el bucle while
counter = 0
Output.
Dentro del bucle
Dentro del bucle
Dentro del bucle
Dentro del else
9. Funciones
9.1. ¿Qué es una función en Python?
En Python, una función es un grupo de sentencias relacionadas que realizan una
tarea específica.
Las funciones ayudan a dividir nuestro programa en partes más pequeñas y mo-
dulares. A medida que nuestro programa crece más y más, las funciones lo hacen
más organizado y manejable.
donde:
5
La denominación de funciones sigue las mismas reglas de escritura de identificadores en Python.
Sintáxis
return [lista_expresion]
Esta declaración puede contener una expresión que se evalúa y se devuelve el valor.
Si no hay una expresión en la declaración o la sentencia return no está presente,
la función devolverá el objeto None.
Por ejemplo:
def absolute_value(num):
"""Esta función retorna el valor
absoluto del numero ingresado"""
if num >= 0:
return num
else:
return -num
# Output: 2
print(absolute_value(2))
# Output: 4
print(absolute_value(-4))
tipo_derivados(’Opciones’,’Europeas’)
tipo_derivados(tipo=’Opciones’,subtipo=’Europeas’)
Argumentos Default: Al escribir una función, puede definir un valor por default
para cada parámetro. Si se proporciona un valor para un argumento al invocar la
función, Python utiliza el valor del argumento. Si no es así, utiliza el valor por
default del argumento. La utilización de los valores propuestos puede simplificar
la utilización de la función y aclarar las formas en que se utilizan normalmente
las funciones. Cuando utilice valores predeterminados, cualquier argumento con
un valor predeterminado debe aparecer después de todos los argumentos que no
tienen valores predeterminados. Esto permite a Python continuar interpretando
correctamente los argumentos posicionales.
def tipo_derivados(subtipo,tipo=’Opciones’)
"""Información acerca de derivados financieros"""
print("\nUno de los tipos de activos derivados es: "+ tipo +".")
print("Se tiene como subtipos: "+subtipo+".")
tipo_derivados(subtipo=’Europeas’)
Argumentos opcionales: A veces tiene sentido hacer que un argumento sea op-
cional para que quienes utilizan la función, puedan elegir proporcionar información
adicional sólo si así lo desean. Puede utilizar valores default para hacer que un
argumento sea opcional.
Ejemplo:
Definimos la función formato de nombre, donde el segundo nombre es opcional.
def get_formatted_name(first_name, last_name, middle_name=’’):
"""Return a full name, neatly formatted."""
if middle_name:
full_name = first_name + ’ ’ + middle_name + ’ ’ + last_name
else:
full_name = first_name + ’ ’ + last_name
return full_name.title()
Para hacer que el segundo nombre sea opcional, se asignó al argumento middle_name
un valor default vacío y lo que hace que se ignore el argumento a menos que el
usuario proporcione un valor.
# o también
def f(argumentos):
return resultado
Ejemplo.
f= lambda a,b,c=1: (4*a-b)/c
9.3. Docstring
La primera cadena después del encabezado de la función se denomina docstring y
es la abreviatura de cadena de documentación. Se utiliza para explicar brevemente,
lo que hace una función.
Aunque opcional, la documentación es una buena práctica de programación. A
menos que pueda recordar lo que comió la semana pasada, siempre documente su
código.
En el ejemplo anterior, tenemos una cadena de documentos inmediatamente debajo
del encabezado de la función.
Por lo general, se usan comillas triples para que la cadena de documentación
pueda extenderse hasta varias líneas. Esta cadena está disponible como el atributo
__doc__ de la función.
Por ejemplo:
print(greet.__doc__)
Esta función saluda
a la persona que es pasada
como parametro
∗ Los parámetros y las variables definidas dentro de una función no son visibles
desde afuera. Por lo tanto, tienen un alcance local.
∗ La vida útil de las variables dentro de una función es siempre que la función
se ejecute.
∗ Se destruyen una vez que regresamos de la función. Por lo tanto, una función
no recuerda el valor de una variable de sus llamadas anteriores.
Aquí hay un ejemplo para ilustrar el alcance de una variable dentro de una función.
def my_func():
x = 10
print("Valor dentro de la función:",x)
x = 20
my_func()
print("Valor fuera de la función:",x)
Salida
Valor dentro de la función: 10
Valor fuera de la función: 20
Almacenar sus funciones en un archivo separado: permite ocultar los detalles del
código de su programa y centrarse en su lógica de nivel superior. También, permite
reutilizar funciones en muchos programas diferentes.
pizza.py
def make_pizza(size, *toppings):
"""Summarize the pizza we are about to make."""
print("\nMaking a " + str(size) +
"-inch pizza with the following toppings:")
for topping in toppings:
print("- " + topping)
programa_principal.py
import pizza
pizza.make_pizza(16, ’pepperoni’)
pizza.make_pizza(12, ’mushrooms’, ’green peppers’, ’extra cheese’)
∗ Esta primera aproximación a la importación, hace que todas las funciones del
módulo estén disponibles en su programa.
Movie
Class
The fault in
Love actually Sarat
our stars
Objects
movie
name
Name year
genre
director
producer Class
Attributes actors
music_director
story_writer
getdata()
Behaviour putdata()
def __setup_parameters__(self):
""" Required calculations for the model """
self.M = self.N + 1 # Number of terminal nodes of tree
self.u = 1 + self.pu # Expected value in the up state
self.d = 1 - self.pd # Expected value in the down state
self.qu = (math.exp((self.r-self.div)*self.dt) -
self.d) / (self.u-self.d)
self.qd = 1-self.qu
def _initialize_stock_price_tree_(self):
# Initialize terminal price nodes to zeros
self.STs = np.zeros(self.M)
def _initialize_payoffs_tree_(self):
# Get payoffs when the option expires at terminal nodes
payoffs = np.maximum(
0, (self.STs-self.K) if self.is_call
else(self.K-self.STs))
return payoffs
11. Paquetes
11.1. ¿Qué son los paquetes?
Normalmente no almacenamos todos nuestros archivos en nuestra computadora en
la misma ubicación. Utilizamos una jerarquía de directorios bien organizada para
facilitar el acceso.
A medida que nuestro programa de aplicación crece en tamaño con muchos módu-
los, colocamos módulos similares en un paquete y diferentes módulos en paquetes
diferentes. Esto hace que un proyecto (programa) sea fácil de gestionar y concep-
tualmente claro.
Un archivo que contiene código Python, por ejemplo: example.py, se llama mó-
dulo y su nombre de módulo sería example.
import math
print("El valor de pi es", math.pi)
Si el nombre de una función que está importando puede entrar en conflicto con
un nombre existente en el programa o si el nombre de la función es largo, puede
utilizar un sobrenombre corto y único.
import math as m
print("El valor de pi es", m.pi)
Hemos cambiado el nombre del módulo math por m. Esto nos puede ahorrar tiempo
de escritura en algunos casos.
Tenga en cuenta que el nombre math no está reconocido en nuestro alcance; por
lo tanto, math.pi es inválido, m.pi es la implementación correcta.
Con esta sintaxis, no es necesario utilizar la notación por puntos cuando se llama
a una función.
Ejemplo.
# importando solo pi del modulo math
e
2.718281828459045
Ejemplo.
# import todos los nombres del modulo estandar math
Importamos todas las definiciones del módulo matemático. Esto hace que todos
los nombres, excepto los que comienzan con un guión bajo, sean visibles en nuestro
alcance.
Importar todo con el símbolo asterisco (*) no es una buena práctica de progra-
mación. Esto puede llevar a definiciones duplicadas para un identificador. También
dificulta la legibilidad de nuestro código.
El mejor enfoque es importar la función o funciones que desee, o importar el
módulo completo y utilizar la notación por puntos. Esto conduce a un claro código
que es fácil de leer y entender.
Podemos agregar modificar esta lista para agregar nuestra propia ruta.
Podemos ver que nuestro código fue ejecutado solo una vez. Esto quiere decir que
nuestro módulo fue importado una sola vez.
Ahora bien, si nuestro módulo cambió durante el curso del programa, tendríamos
que volver a cargarlo. Una forma de hacerlo es reiniciar el intérprete. Pero esto no
ayuda mucho.
Python proporciona una forma limpia de hacer esto. Podemos usar la función
reload() dentro del módulo imp para recargar un módulo.
>>> import imp
>>> import my_module
Este codigo se ha ejecutado
Por ejemplo, hemos definido una función add() en el módulo example que que
se mencionó anteriormente.
>>> dir(example)
[’__builtins__’,
’__cached__’,
’__doc__’,
’__file__’,
’__initializing__’,
’__loader__’,
’__name__’,
’__package__’,
’add’]
Aquí, podemos ver una lista ordenada de nombres (junto con add). Todos los
demás nombres que comienzan con un guión bajo son atributos predeterminados
de Python asociados con el módulo (no los definimos nosotros mismos).
Comando array(), se utiliza para convertir objetivos en array, por ejemplo listas
y tuplas.
mylist = [1, 2, 3]
myarray = np.array(mylist)
myarray
array([1, 2, 3])
array([[1, 2, 3],
[0, 0, 0],
[0, 0, 0]])
Con el comando array(), se puede crear una matriz usando una lista con repeti-
ciones.
np.array([1, 2, 3] * 3)
array([1, 2, 3, 1, 2, 3, 1, 2, 3])
Otra forma de repetir los elementos de una matriz es usar el comando repeat.
np.repeat([1, 2, 3], 3)
array([1, 1, 1, 2, 2, 2, 3, 3, 3])
El comando ones() devuelve un nuevo array donde sus elementos son valor 1, se
debe indicar el número de filas y el número de columnas.
np.ones((3, 2))
array([[1., 1.],
[1., 1.],
[1., 1.]])
El comando zeros() devuelve una nueva matriz donde sus elementos son ceros.
np.zeros((2, 3))
El comando eye() devuelve una matriz con valor 1 en la diagonal y ceros en las
demás posiciones.
myarray = np.eye(3)
array([1, 1, 1])
La función arange() ayuda a grabar una secuencia, que tiene algún valor inicial
(start), algún valor final (stop), la diferencia entre los términos consecutivos (step)
y el tipo de datos (dtype).
numpy.arange(start, stop, step, dtype)
a=np.arange(3,25,2, int)
a
array([3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23])
d
array([11., 12.6, 14.2, 15.8, 17.4, 19., 20.6, 22.2, 23.8,
25.4, 27.])
f
(array([11., 12.45454545, 13.90909091, 15.36363636,
16.01010102, 18.27272727, 19.72727273, 21.10101010,
22.63636364, 24.09090909, 25.54545455]), 1.4545454545454546)
Nombre Descripción
append() Añadir un elemento al final
insert() Añadir el elemento en la posición especificada. La función
tiene dos argumentos: el primero es el elemento y el
segundo es la posición
count() Esto cuenta el número de veces que se repite el argumento
pop() Elimina el elemento superior del array
remove() Elimina el elemento de una posición determinada
reverse() Invierte el orden de los elementos en el array
tostring() Convierte el array dado en una cadena
Para ver el tipo de datos de los elementos en la matriz usamos el comando dtype.
p.dtype
dtype(’int32’)
dtype(’float32’)
12.4. Operaciones
Recordemos que los operadores aritméticos son: +, −,∗,/ y ∗∗, para realizar sumas,
restas, multiplicaciones, divisiones y potencias a nivel de elementos. A continuación
algunos ejemplos de operaciones con array.
x=np.array([1, 2, 3])
y=np.array([4, 5, 6])
print(x + y) # Suma
[5 7 9]
print(x - y) # Resta
[-3 -3 -3]
print(x * y) # multiplicación
[1 2 3] * [4 5 6] = [4 10 18]
print(x / y) # división
[1 2 3] / [4 5 6] = [0.25 0.4 0.5]
print(x**2) # potenciación
[1 4 9]
r
32
np.transpose
array([[ 4, 16],
[ 5, 25],
[ 6, 36]])
12.5. Broadcasting
Python aplica las operaciones elemento por elemento no sólo en suma o resta,
sino también en el caso de multiplicación y división, tal como se mostró en la
sección 12.4, entonces surge la pregunta ¿Qué pasa si se suman dos arrays de
diferentes dimensiones? Python tiene una forma de lidiar con tales situaciones:
es se denomina Broadcasting.
Se tiene el siguiente array "m", con la que se aplicaran distintas funciones mate-
máticas.
m = np.array([-4, -2, 1, 3, 5])
Función suma.
m.sum()
In[1]: 3
Función máximo
m.max()
In[2]: 5
Función mínimo
m.min()
In[3]:-4
Función promedio
m.mean()
In[4]: 0.6
Para mayor detalle y exploración de las funciones agregadas que tiene NumPy,
ingresar al link https://www.numpy.org/devdocs/reference/index.html#reference
12.7. Indexación
La sintaxis estandar de indexación en Pyhton es: x[obj], donde x es la matriz
y obj la selección de elementos. Se tienen 3 tipos de indexación disponible: basic
slicing, advanced indexing y field access,
array([ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144])
myarray[-5::-2]
array([64, 36, 16, 4, 0])
array([[ 0, 1, 2, 3, 4, 5],
[ 6, 7, 8, 9, 10, 11],
[12, 13, 14, 15, 16, 17],
[18, 19, 20, 21, 22, 23],
[24, 25, 26, 27, 28, 29],
[30, 31, 32, 33, 34, 35]])
r[:2, :-1]
array([[ 0, 1, 2, 3, 4],
[ 6, 7, 8, 9, 10]])
Ejemplo.
t = np.array([[1,2],[3,4],[5,6]])
x[[0,1,2],[0,1,0]]
array([1,4,5])
Ejemplo.
x = np.array([1., -1., -2., 3])
x[x < 0] += 20
x
name=[’Harsh’,’Naved’,’Aman’,’Lovish’]
age=[100,70,24,18]
salary=[75500.00,65500.00,55500.00,45500.00]
data=np.zeros(4,dtype={’names’:(’name’,’age’,’salary’),
’formats’:(’U10’,’i4’,’f8’)})
data[’name’]=name
data[’age’]=age
data[’salary’]=salary
print(data)
#Output
Una vez que se ha creado un array estructurado, se puede acceder a los datos de
la forma habitual. Por ejemplo, para mostrar el valor de un atributo en particular,
podemos simplemente mencionar el nombre del atributo en comillas simples dentro
de los corchetes.
data[’name’]
#Output
data[’name’]
array([’Harsh’, ’Naved’, ’Aman’, ’Lovish’], dtype=’<U10’)
data[’age’]
array([100, 70, 24, 18])
data[’salary’]
array([ 75500., 65500., 55500., 45500.])
data[1]
(’Naved’, 70, 65500.0)
13. Pandas
13.1. ¿Qué es Pandas?
Pandas es un paquete que proporciona un conjunto completo de estructuras de
datos para explorar, limpiar y manipular datos, además de realizar diversos análisis
estadísticos y financieros.
13.2. Series
Series es el principal componente de Pandas y representa un array etiquetado
unidimensional basado en ndarray de NumPy. Series amplía la funcionalidad
del ndarray NumPy añadiendo un conjunto de etiquetas asociadas que se utilizan
para indexar los elementos del array.
Por ejemplo, el siguiente comando crea un objeto Series de 100 números aleatorios
normalmente distribuidos.
In [1]:
np.random.seed(1)
s = pd.Series(np.random.randn(100))
s
Out[1]:
0 1.624345
1 -0.611756
2 -0.528172
3 -1.072969
...
96 -0.343854
97 0.043597
98 -0.620001
99 0.698032
Length: 100, dtype: float64
Out[2]:
-0.528171752263
Out[3]:
2 -0.528172
5 -2.301539
20 -1.100619
dtype: float64
Tenga en cuenta que slicing no sólo devuelve los valores sino también cada ele-
mento (etiqueta de índice y valor) de la serie con las etiquetas especificadas.
In [7]:
s.tail()
Out[5]:
95 0.077340
96 -0.343854
97 0.043597
98 -0.620001
99 0.698032
dtype: float64
Out[7]:
a 1
b 2
c 3
d 4 dtype: int64
Un Series puede ser creada directamente desde un diccionario Python. Las claves
del diccionario se utilizan como etiquetas de índice para Series:
In [8]:
s2 = pd.Series({’a’: 1, ’b’: 2, ’c’: 3, ’d’: 4, ’e’: 5})
s2
Out[8]:
a 1
b 2
c 3
d 4
e 5
dtype: int64
Out[9]:
10
Out[11]:
9
Out[14]:
a 1
b 2
c 3
d 4
dtype: int64
In [15]:
s4 = pd.Series([4, 3, 2, 1], index=[’d’, ’c’, ’b’, ’a’])
s4
Out[15]:
d 4
c 3
b 2
a 1
dtype: int64
Out[15]:
a 2
b 4
c 6
d 8
dtype: int64
13.3. El DataFrame
Series es la base para la representación y manipulación de datos en Pandas,
pero como sólo puede asociar un único valor con cualquier etiqueta de índice
dada, termina teniendo una capacidad limitada para modelar múltiples variables
de datos en cada etiqueta de índice.
Un DataFrame tiene dos ejes, horizontal y vertical. Las funciones de los Pandas se
pueden aplicarse a cualquiera de los dos ejes, en esencia, indicando que se aplica
a todos los valores de las filas seleccionadas o a todos los ítems de las columnas
específicadas.
Out[16]:
0 1
0 10 11
1 20 21
Cada fila del array forma una fila en el DataFrame. Como no especificamos un
índice, Pandas crea un índice int64 por defecto de la misma manera que un
Series. Como tampoco especificamos los nombres de columna, Pandas también
asigna los nombres para cada columna con una serie entera basada en cero.
Out[17]:
0 1 2 3 4
0 10 11 12 13 14
1 15 16 17 18 19
Out[19]:
a b
0 10 11
1 20 21
Out[20]:
Index([u’a’, u’b’], dtype=’object’)
In [21]:
df.columns = [’c1’, ’c2’]
df
Out[26]:
c1 c2
0 10 11
1 20 21
Out[22]:
c1 c2
r1 0 1
r2 2 3
Out[23]:
c1 c2
0 1 6
1 2 7
2 3 8
3 4 9
4 5 10
En el ejemplo anterior se aprecia que los dos primeros objetos Series no tenían un
índice especificado por lo que ambos fueron indexados con 0 a 4. El tercer Series
tiene valores de índice; por lo tanto, los valores para esos índices se colocan en
el DataFrame en la fila con el índice correspondiente de las columnas anteriores.
Entonces, Pandas completa automáticamente con NaN para los valores que no
fueron suministrados.
Otra forma de crear un DataFrame es importar datos de un archivo csv. Excel, para
esto se utiliza la función read_csv() o read_excel() respectivamente. Para ex-
portar archivo externos en otras extensiones revisar el link https://pandas.pydata.org/pandas-
docs/stable/reference/io.html.
Out[25]:
Sector Price Book Value
Symbol
MMM Industrials 141.14 26.668
ABT Health Care 39.60 15.573
ABBV Health Care 53.95 2.954
ACN Information Technology 79.79 8.326
ACE Financials 102.91 86.897
Out[26]:
Price Book Value
Symbol
MMM 141.14 26.668
ABT 39.60 15.573
ABBV 53.95 2.954
Out[27]:
Price Sector
Symbol
MMM 141.14 Industrials
ABT 39.60 Health Care
ABBV 53.95 Health Care
ACN 79.79 Information Technology
... ... ...
YUM 74.77 Consumer Discretionary
ZMH 101.84 Health Care
ZION 28.43 Financials
ZTS 30.53 Health Care
[500 rows x 2 columns]
Out[28]:
Symbol
MMM 141.14
ABT 39.60
ABBV 53.95
ACN 79.79
...
YUM 74.77
ZMH 101.84
ZION 28.43
ZTS 30.53
Name: Price, dtype: float64
Ejemplos:
In [29]:
sp500[:3]
Out[29]:
Sector Price Book Value
Symbol
MMM Industrials 141.14 26.668
ABT Health Care 39.60 15.573
ABBV Health Care 53.95 2.954
In [30]:
sp500[’XYL’:’YUM’]
Out[30]:
Sector Price Book Value
Symbol
XYL Industrials 38.42 12.127
YHOO Information Technology 35.02 12.768
YUM Consumer Discretionary 74.77 5.147
Out[31]:
Sector Price Book Value
Symbol
MMM Industrials 141.14 26.668
MSFT Information Technology 40.12 10.584
Las filas también se pueden extraer indicando la ubicación del índice usando
.iloc[]:
In [32]:
sp500.iloc[[0, 2]]
Out[32]:
Sector Price Book Value
Symbol
MMM Industrials 141.14 26.668
ABBV Health Care 53.95 2.954
Out[33]:
(0, 10)
In [34]:
sp500.iloc[[i1, i2]]
Out[34]:
Sector Price Book Value
Symbol
MMM Industrials 141.14 26.668
A Health Care 56.18 16.928
Un DataFrame también contiene una propiedad .ix[] que puede ser usada
para buscar filas ya sea por la etiqueta de índice o por la ubicación, esencial-
mente combinando .loc y .iloc en una.
Por ejemplo:
In [35]:
sp500.ix[[’MSFT’, ’ZTS’]]
Out[35]:
Sector Price Book Value
Symbol
MSFT Information Technology 40.12 10.584
ZTS Health Care 30.53 2.150
Out[36]:
Sector Price Book Value
Symbol
A Health Care 56.18 16.928
GIS Consumer Staples 53.81 10.236
TRV Financials 92.86 73.056
Los valores escalares se pueden buscar por etiqueta usando .at[] indicando
la etiqueta de la fila y luego el nombre/valor de la columna:
In [37]:
sp500.at[’MMM’, ’Price’]
Out[37]:
141.14
Los valores escalares también pueden ser buscados por ubicación usando
.iat[] indicando la ubicación de la fila como de la columna. Este es el
método preferido para acceder a los valores y resultados individuales.
In [38]:
sp500.iat[0, 1]
Out[38]:
141.14
Por ejemplo, seleccionar todas las compañías que tienen un precio por debajo de
100.0
In [39]:
sp500.Price < 100
Out[39]:
Symbol
MMM False
ABT True
ABBV True
ACN True
...
YUM True
ZMH False
ZION True
ZTS True
Name: Price, Length: 500, dtype: bool
Esto arroja un Series que puede ser usados para seleccionar filas donde el valor
es True:
In [40]:
sp500[sp500.Price < 100]
Out[40]:
Sector Price Book Value
Symbol
ABT Health Care 39.60 15.573
ABBV Health Care 53.95 2.954
ACN Information Technology 79.79 8.326
ADBE Information Technology 64.30 13.262
... ... ... ...
YHOO Information Technology 35.02 12.768
YUM Consumer Discretionary 74.77 5.147
ZION Financials 28.43 30.191
ZTS Health Care 30.53 2.150
In [41]:
sp500[(sp500.Price < 10) & (sp500.Price > 0)] [[’Price’]]
Out[41]:
Symbol Price
FTR 5.81
HCBK 9.80
HBAN 9.10
SLM 8.82
WIN 9.38
Por defecto, cualquier operación aritmética se aplicará a todas las filas y columnas
de un DataFrame y devolverá un nuevo DataFrame con los resultados (dejando el
original sin cambios).
Por ejemplo:
In [42]:
np.random.seed(123456)
df = pd.DataFrame(np.random.randn(5, 4),
columns=[’A’, ’B’, ’C’, ’D’])
In [42]:
df - df.iloc[0]
Una operación aritmética entre dos objetos DataFrame se alineará con las etique-
tas de las columnas y de los índices.
Out[43]:
B C
1 -0.173215 0.119209
2 -2.104569 -0.494929
1 -0.706771 -1.039575
In [44]:
df subframe
Out[44]:
A B C D
0 NaN NaN NaN NaN
1 NaN 0 0 NaN
2 NaN 0 0 NaN
3 NaN 0 0 NaN
4 NaN NaN NaN NaN
∗ Reordena los datos existentes para que coincidan con un conjunto de etique-
tas.
∗ Inserta marcadores NaN donde no existen datos para una etiqueta.
∗ Rellena los datos faltantes para una etiqueta utilizando un tipo de lógica (por
default añadir NaNs).
dtype: float64
Out[47]:
a 1.624345
b -0.611756
c -0.528172
d -1.072969
e 0.865408
dtype: float64
Out[48]:
a 0.000000
c -0.528172
e 0.865408
g NaN
dtype: float64
La reindexación también es útil cuando se desea alinear dos series para realizar una
operación de emparejamiento entre de los elementos de cada serie, pero por alguna
razón, los dos series tenían etiquetas de índice que no se alinearon inicialmente.
Por ejemplo, el primer objeto Series tiene índices como números enteros secuen-
ciales, pero el segundo tiene una representación de cadena de lo que sería números
enteros secuenciales. La adición de ambos Series tiene el siguiente resultado,
donde todos son NaNs y se tiene valores de etiqueta repetidos:
In [49]:
s1 = pd.Series([0, 1, 2], index=[0, 1, 2])
s2 = pd.Series([3, 4, 5], index=[’0’, ’1’, ’2’])
s1 + s2
Out[49]:
0 NaN
1 NaN
2 NaN
0 NaN
1 NaN
2 NaN
dtype: float64
En este caso, Pandas primero intentan alinearse con los índices y al no encontrar
coincidencias, copia las etiquetas de los índices del primer objeto Series e intentan
añadir los índices del segundo objeto Series. Pero como son de otro tipo, se
vuelve a establecer por defecto una secuencia entera basada en cero, lo que da
como resultado valores duplicados. Y finalmente, todos los valores resultantes son
NaN porque la operación intenta añadir el ítem de la primera serie con la etiqueta
entera 0, que tiene el valor 0 pero no puede encontrar el ítem de la otra serie
con la etiqueta entera 0; por lo tanto, el resultado es NaN. Este inconveniente se
soluciona con la reindexación de la segunda serie, convirtiendo los valores a int:
In [50]:
s2.index = s2.reindex.values.astype(int)
s1 + s2
Out[50]:
0 3
1 5
2 7
dtype: int64
La acción por defecto de insertar NaN como un valor omitido durante .reindex()
puede ser cambiada usando el argumento fill_value, que completa con ceros
en lugar de NaN:
In [52]:
s2 = s.copy()
s2.reindex([’a’, ’f’], fill_value=0)
Out[51]:
a 1.624345
f 0.000000
dtype: float64
Cuando se realiza un reindex sobre datos ordenados, como una serie de tiempo, es
posible realizar interpolación o rellenado de valores. Para demostrar el concepto,
usemos el siguiente objeto Series:
In [52]:
s3 = pd.Series([’red’, ’green’, ’blue’], index=[0, 3, 5])
s3
Out[52]:
0 red
3 green
5 blue
dtype: object
Out[53]:
0 red
1 red
2 red
3 green
4 green
5 blue
6 blue
dtype: object
Out[54]:
0 red
1 green
2 green
3 green 4 blue 5 blue 6 NaN dtype: object
Recordemos que para importar datos de archivos csv. usamos la función pd.read_csv().
Y se extraen parte de los datos del DataFrame para fines de los ejemplos.
In [1]:
msft = pd.read_csv("msft.csv", index_col=0, parse_dates=True)
aapl = pd.read_csv("aapl.csv", index_col=0, parse_dates=True)
In [2]:
msft[:3]
In [3]:
aapl[:3]
Pandas ofrecen una gran variedad de funciones para concatenar, fusionar y resstruc-
turar los datos. Estas secciones siguientes nos llevan a través de varios escenarios
comunes de cada uno, utilizando datos de acciones (ejemplos: MSFT y AAPL).
Por ejemplo:
In [4]:
msftA01 = msft[’2019-01’][[’Adj Close’]]
msftA02 = msft[’2019-02’][[’Adj Close’]]
msftA01[:3]
Out[4]:
In [5]:
msftA02[:3]
Out[5]:
Date Adj Close
2019-02-01 27.27
2019-02-02 27.32
2019-02-03 27.59
Out[6]:
In [7]:
aaplA01 = aapl[’2019-01’][[’Adj Close’]]
withDups = pd.concat([msftA01[:3], aaplA01[:3])
withDups
Out[7]:
Out[8]:
Date Adj Close
MSFT 2019-01-03 24.42
2019-01-04 25.00
2019-01-05 25.25
AAPL 2019-01-03 55.41
2019-01-04 55.71
2019-01-05 56.33
Out[9]:
In [10]:
msftAV = msft[[’Adj Close’, ’Volume’]]
aaplAV = msft[[’Adj Close’, ’Volume’]]
pd.concat([msftAV, aaplAV])
Out[10]:
Out[11]:
Date Adj Close Volume
2019-01-03 24.42 64731500
2019-01-04 25.00 80516100
2019-01-05 25.25 56081400
2019-01-06 25.64 99455500
... ... ...
2019-12-24 70.72 NaN
2019-12-26 69.74 NaN
2019-12-27 70.02 NaN
2019-12-28 69.28 NaN
[498 rows x 2 columns]
Dado que las filas que se originan desde el DataFrame aaplA no tienen la
columna Volumen, los Pandas insertan NaN en la columna de Volumen para
esas filas.
El conjunto de columnas que resulta de una concatenación a lo largo del eje
de la fila es el resultado del álgebra relacional a través de los nombres de las
columnas. En este escenario por defecto, la columna resultante es la unión
de los nombres de las columnas de cada DataFrame. Esto se puede cambiar
a una intersección utilizando el parámetro de join. Por ejemplo:
In [12]:
pd.concat([msftAV, aaplA], join=’inner’)
Out[12]:
Date Adj Close
2019-01-03 24.42
2019-01-04 25.00
2019-01-05 25.25
2019-01-06 25.64
... ...
2019-12-24 70.72
2019-12-26 69.74
2019-12-27 70.02
2019-12-28 69.28
[498 rows x 1 columns]
Out[13]:
Out[14]:
MSFT AAPL
Date Adj Close Volume Adj Close Volume
2019-01-03 24.42 64731500 55.41 75555200
2019-01-04 25.00 80516100 55.71 65005500
2019-01-05 25.25 56081400 56.33 67817400
2019-01-06 25.64 99455500 NaN NaN
2019-01-09 25.31 59706800 NaN NaN
Out[15]:
Date Adj Close Adj Close
2019-01-03 24.42 55.41
2019-01-04 25.00 55.71
2019-01-05 25.25 56.33
El DataFrame resultante sólo tiene tres filas porque esas etiquetas de índice
eran las únicas comunes en los dos objetos DataFrame concatenados.
Si desea ignorar índices en el resultado de pd.concat(), puede utilizar el
parámetro ignore_index=True, que no considerará el índice y creará un
índice entero basado en cero por defecto, como se muestra aquí:
In [16]:
pd.concat([msftA[:3], aaplA[:3]], ignore_index=True)
Out[16]:
Adj Close
0 24.42
1 25.00
2 25.25
3 55.41
4 55.71
5 56.33
Out[17]:
Date Adj Close
0 2019-01-03 24.42
1 2019-01-04 25.00
2 2019-01-05 25.25
In [18]: msftVR[:3]
Out[18]:
Date Volume
0 2019-01-03 64731500
1 2019-01-04 80516100
2 2019-01-05 56081400
En lugar de usar Fecha como índice, éstos tienen Fecha como columna para
que se pueda utilizar en la fusión. Nuestro objetivo es crear un DataFrame
que contenga una columna Date y las columnas AdjClose y Volume. Esto se
puede lograr con el siguiente código.
In [19]:
msftCVR = pd.merge(msftAR, msftVR)
msftCVR[:5]
Out[19]:
Date Adj Close Volume
0 2019-01-03 24.42 64731500
1 2019-01-04 25.00 80516100
2 2019-01-05 25.25 56081400
3 2019-01-06 25.64 99455500
4 2019-01-09 25.31 59706800
Out[20]:
Date Adj Close
0 2019-01-03 24.42
1 2019-01-04 25.00
2 2019-01-05 25.25
3 2019-01-06 25.64
2019-01-09 25.31
In [21]:
msftVR2_4 = msftVR[2:4]
msftVR2_4
Out[21]:
Date Volume
2 2019-01-05 56081400
3 2019-01-06 99455500
Unión interna (inner): ya que sólo hay dos filas con fechas coincidentes,
el resultado sólo tiene dos filas y fusiona los objetos DataFrame donde los
valores de Fecha son comunes.
In [22]:
pd.merge(msftAR0_5, msftVR2_4)
Out[22]:
Date Adj Close Volume
0 2019-01-05 25.25 56081400
1 2019-01-06 25.64 99455500
Esto puede cambiarse por una unión externa con how=’outer’. Se devuel-
ven todas las filas del DataFrame externo (msftAR0_5), y los valores que
no se encuentran en el DataFrame interno (msftVR2_4) se sustituyen por
NaN:
In [23]:
pd.merge(msftAR0_5, msftVR2_4, how=’outer’)
Out[23]:
Date Adj Close Volume
0 2019-01-03 24.42 NaN
1 2019-01-04 25.00 NaN
2 2019-01-05 25.25 56081400
3 2019-01-06 25.64 99455500
4 2019-01-09 25.31 NaN
3. Pivot
Los datos financieros se almacenan a menudo en un formato en el que los
datos no están normalizados y, por lo tanto, tienen valores repetidos en mu-
chas columnas o valores que lógicamente deberían existir en otras tablas. Un
ejemplo de esto sería el siguiente, donde los precios históricos para múlti-
ples acciones se representan en un único DataFrame utilizando una columna
Symbol. El siguiente código crea este esquema.
In [24]:
msft.insert(0, ’Symbol’, ’MSFT’)
aapl.insert(0, ’Symbol’, ’AAPL’)
combined = pd.concat([msft, aapl]).sort_index()
s4p = combined.reset_index();
s4p[:5]
Out[24]:
Date Symbol Open High Low Close Volume Adj Close
0 2019-01-03 MSFT 26.55 26.96 26.39 26.77 64731500 24.42
1 2019-01-03 AAPL 409.40 412.50 409.00 411.23 75555200 55.41
2 2019-01-04 MSFT 26.82 27.47 26.78 27.40 80516100 25.00
3 2019-01-04 AAPL 410.00 414.68 409.28 413.44 65005500 55.71
4 2019-01-05 MSFT 27.38 27.73 27.29 27.68 56081400 25.25
Out[25]:
Date AAPL MSFT
2019-01-03 55.41 24.42
2019-01-04 55.71 25.00
2019-01-05 56.33 25.25
Esta función toma todos los valores distintos de la columna Símbolo, los
gira en columnas en el nuevo DataFrame, y luego incluye los valores en esas
columnas desde el valor AdjClose para el símbolo específico del DataFrame
original.
Out[26]:
Date Symbol
2019-01-03 AAPL 55.41
MSFT 24.42
2019-01-04 AAPL 55.71
MSFT 25.00
...
2019-12-27 AAPL 70.02
MSFT 25.29
2019-12-28 AAPL 69.28
MSFT 24.91
dtype: float64
Esto ha creado un nuevo índice con un nivel adicional llamado Símbolo. Cada
fila es entonces indexada por Fecha y Símbolo, y para cada nivel único de
Fecha y Símbolo, Pandas ha insertado el valor de AdjClose apropiado.
El resultado de esto permite la búsqueda eficiente de cualquier valor de
AdjClose utilizando el índice. Por ejemplo
In [27]:
stackedCloses.ix[’2019-01-03’, ’AAPL’]
Out[27]:
55.41
Out[28]:
Symbol
AAPL 55.41
MSFT 24.42
dtype: float64
Out[29]:
Date
2019-01-03 24.42
2019-01-04 25.00
2019-01-05 25.25
2019-01-06 25.64
...
2019-12-24 25.38
2019-12-26 25.20
2019-12-27 25.29
2019-12-28 24.91
dtype: float64
Out[30]:
5. Melting
Out[31]:
Date Symbol variable value
0 2019-01-03 MSFT Open 26.55
1 2019-01-03 AAPL Open 409.40
2 2019-01-04 MSFT Open 26.82
3 2019-01-04 AAPL Open 410.00
4 2019-01-05 MSFT Open 27.38
Out[32]:
Date Symbol variable value
0 2019-01-03 MSFT Open 26.55
498 2019-01-03 MSFT High 26.96
996 2019-01-03 MSFT Low 26.39
1494 2019-01-03 MSFT Close 26.77
1992 2019-01-03 MSFT Volume 64731500.00
2490 2019-01-03 MSFT Adj Close 24.42
1. Dividir
s4g[:5]
Out[33]:
Date Year Month Symbol Adj Close
0 2019-01-03 2019 1 MSFT 24.42
1 2019-01-03 2019 1 AAPL 55.41
2 2019-01-04 2019 1 MSFT 25.00
3 2019-01-04 2019 1 AAPL 55.71
4 2019-01-05 2019 1 MSFT 25.25
Estos datos difieren de los anteriores, ya que sólo se utiliza el valor de AdjClose
y la columna Date se divide en otras dos columnas, Year y Month. Esta
división de la fecha se hace para poder proporcionar la capacidad de agrupar
los datos por Mes y Año para cada variable de Símbolo.
Out[34]:
<Pandas.core.groupby.DataFrameGroupBy object at 0x7ffaeeb49a10>
Out[35]:
dict
In [36]:
grouped.groups
Out[36]:
{u’AAPL’: [1, 3, 5, 7, 9, 11, 13, 14, 16, 18, 20, 23, 25, 27, 29,
30, 33, 34, 37, 38, 41, 43, 45, 46, 48, 50, 53, 54, 56, 58, 61,
63, 64, 67, 69, 71, 72, 75, 77, 79, 81, 82, 84, 89, 91, 92, 94,
...
452, 455, 456, 458, 460, 463, 464, 466, 468, 471, 472, 474, 476,
478, 480, 482, 484, 487, 488, 490, 492, 494, 497]
’MSFT’: [0, 2, 4, 6, 10, 12, 15, 17, 19, 21, 22, 24, 26, 28, 31, 32,
...
477, 479, 481, 483, 485, 486, 489, 491, 493, 495, 496]}
Out[37]:
(2, 2)
In [39]:
print_groups(grouped)
Out[39]:
AAPL
Date Year Month Symbol Adj Close
1 2019-01-03 2019 1 AAPL 55.41
3 2019-01-04 2019 1 AAPL 55.71
5 2019-01-05 2019 1 AAPL 56.33
7 2019-01-06 2019 1 AAPL 56.92
9 2019-01-09 2019 1 AAPL 56.83
MSFT
Date Year Month Symbol Adj Close
0 2019-01-03 2019 1 MSFT 24.42
2 2019-01-04 2019 1 MSFT 25.00
4 2019-01-05 2019 1 MSFT 25.25
6 2019-01-06 2019 1 MSFT 25.64
8 2019-01-09 2019 1 MSFT 25.31
Se puede crear, para cada valor distinto en la columna Símbolo del DataFrame
original, un grupo que consiste en un DataFrame. Luego copia las columnas
y los datos no agrupados en cada uno de esos objetos DataFrame y luego
utiliza el comando de las columnas especificadas como nombre de grupo.
La función.size() del objeto da un buen resumen del tamaño de todos los
grupos:
In [40]:
grouped.size()
Out[40]:
Symbol
AAPL 249
MSFT 249
dtype: int64
Out[41]:
Date Year Month Symbol Adj Close
0 2019-01-03 2019 1 MSFT 24.42
2 2019-01-04 2019 1 MSFT 25.00
4 2019-01-05 2019 1 MSFT 25.25
6 2019-01-06 2019 1 MSFT 25.64
.. ... ... ... ... ...
491 2019-12-24 2019 12 MSFT 25.38
493 2019-12-26 2019 12 MSFT 25.20
495 2019-12-27 2019 12 MSFT 25.29
496 2019-12-28 2019 12 MSFT 24.91
[249 rows x 5 columns]
Out[42]:
Date Year Month Symbol Adj Close
1 2019-01-03 2019 1 AAPL 55.41
3 2019-01-04 2019 1 AAPL 55.71
5 2019-01-05 2019 1 AAPL 56.33
7 2019-01-06 2019 1 AAPL 56.92
9 2019-01-09 2019 1 AAPL 56.83
In [43]:
mi = s4g.set_index([’Symbol’, ’Year’, ’Month’])
mi
Out[43]:
Ahora se puede realizar la agrupación utilizando los niveles del índice jerár-
quico. Los siguientes grupos por el nivel de índice 0.
In [44]:
mig_l1 = mi.groupby(level=0)
print_groups(mig_l1)
Out[44]:
Symbol Year Month Date Adj Close
AAPL 2019 1 2019-01-03 55.41
1 2019-01-04 55.71
1 2019-01-05 56.33
1 2019-01-06 56.92
1 2019-01-09 56.83
Out[45]:
Symbol Year Month Date Adj Close
AAPL 2019 1 2019-01-03 55.41
1 2019-01-04 55.71
1 2019-01-05 56.33
1 2019-01-06 56.92
1 2019-01-09 56.83
...
2. Agregar
Out[46]:
Out[47]:
Out[48]:
Symbol Year Month mean std
AAPL 2019 1 57.75 1.80
2 67.05 3.57
3 77.82 4.16
4 81.66 3.06
... ... ...
MSFT 2019 9 28.64 0.43
10 27.04 0.67
11 26.00 1.00
12 25.31 0.36
[24 rows x 2 columns]
14. Matplotlib
14.1. Introducción
Matplotlib es un paquete para realizar gráficos y visualizar los datos. La arquitectura
de matplotlib está estructurada en tres capas, que son colocadas en tres niveles diferentes.
La comunicación es unidireccional, es decir, cada capa puede comunicarse con la capa
subyacente.
Backend Layer: la capa que funciona en el nivel más bajo es la capa de fondo.
Esta capa contiene las API matplotlib y un conjunto de clases que juegan el rol
de implementación de los elementos gráficos en un nivel bajo.
Artist Layer: en esta capa se tiene a todos los elementos que conforman un
gráfico, como el título, etiquetas de ejes, marcadores, etc. Cada elemento de un
gráfico corresponde a esta capa artística.
Pylab y Pyplot.
Pylab es un módulo que se instala junto con matplotlib, mientras que pyplot es
un módulo interno de matplotlib. Pylab combina la funcionalidad de pyplot con las
capacidades de NumPy y, por lo tanto, no necesita importar NumPy por separado. El
paquete pyplot proporciona la interfaz clásica de Python, tiene su propio espacio de
nombres y requiere la importación de NumPy por separado.
14.2. Pyplot
El módulo pyplot es un conjunto de funciones que le permiten utilizar matplotlib de
forma muy parecida a MATLAB.
Se iniciará con un gráfico sencillo, importando el módulo pyplot, que en general
se renombra como plt. Por lo tanto, puede simplemente pasar los valores que desea
representar como una secuencia de números enteros y estos se asocian a la secuencia
natural de valores del eje x: 0,1,2,3.... Ver el siguiente ejemplo:
Finalmente, se utiliza la función show(), para mostrar una ventana de gráfico, repre-
sentado éste dentro de ella; esta ventana se caracteriza por una barra de herramientas,
en la parte superior con un conjunto de botones, que se describen a continuación:
Icono Descripción
Generalmente un gráfico representa pares de valores (x,y), por lo que para definir
un gráfico correctamente, debe definir dos matrices: la primera que contenga los valores
en el eje x y la segunda que contenga los valores en el eje y. En el gráfico generado, el
eje x tendrá valores de 0 a (n-1) y el eje y tendrá los valores de la lista dada.
Las propiedades del gráfico son:
Los objetos que forman un gráfico tienen muchos atributos que los caracterizan. Todos
los atributos son valores predeterminados, pero se pueden configurar mediante el uso de
argumentos, a menudo referidos como kwargs. Estas palabras clave se definen como
argumentos a las funciones. Ejemplo de un gráfico lineal.
matplotlib.pyplot.plot(*args, **kwargs)
In [4]: plt.plot([1,2,4,2,1,0,1,2,1,4],linewidth=2.0)
Ejemplo de subgráficos.
In [5]: t = np.arange(0,5,0.1)
y1 = np.sin(2*np.pi*t)
y2 = np.sin(2*np.pi*t)
In [6]: plt.subplot(211)
plt.plot(t,y1,’b-.’)
plt.subplot(212)
plt.plot(t,y2,’r--’)
Out[6]: [<matplotlib.lines.Line2D at 0xd47f518>]
14.4.1. Texto
Para incluir el título a un gráfico se utiliza la función title().
Para añadir las etiquetas de los ejes es posible mediante el uso de otras dos funcio-
nes específicas: xlabel() e ylabel(). Estas funciones toman como argumento
una cadena, que será el texto mostrado.
También es posible modificar el color de las etiquetas de los ejes, modificar el título
cambiando la fuente y aumentando el tamaño de los caracteres para acentuar el título
del gráfico, como se muestra a continuación:
In [10]: plt.axis([0,5,0,20])
plt.title(’My first plot’,fontsize=20,fontname=’Times New Roman’)
plt.xlabel(’Counting’,color=’gray’)
plt.ylabel(’Square values’,color=’gray’)
plt.plot([1,2,3,4],[1,4,9,16],’ro’)
Out[10]: [<matplotlib.lines.Line2D at 0x11f17470>]
Como se puede apreciar en la figura anterior, cada punto del gráfico tiene una eti-
queta. Además se puede incluir expresiones en LaTeX, por lo tanto permite insertar
expresiones matemáticas en el gráfico. Para ello, se puede añadir una expresión LaTeX
al texto entre dos caracteres $. Generalmente hay que preceder a la cadena que contiene
expresiones LaTeX con una r, que indica texto sin procesar, para evitar secuencias de
escape no intencionadas. Por lo tanto, a modo de ejemplo, se puede añadir la fórmula
que describe la tendencia seguida por el punto del gráfico del ejemplo anterior y ser
encerrado en un cuadro delimitador de color.
Ejemplo de gráfico con texto LaTeX.
In [12]: plt.axis([0,5,0,20])
plt.title(’My first plot’,fontsize=20,fontname=’Times New Roman’)
plt.xlabel(’Counting’,color=’gray’)
plt.ylabel(’Square values’,color=’gray’)
plt.text(1,1.5,’First’)
plt.text(2,4.5,’Second’)
plt.text(3,9.5,’Third’)
plt.text(4,16.5,’Fourth’)
plt.text(1.1,12,r’$y = x^2$’,fontsize=20,bbox={’facecolor’:’yellow’,
’alpha’:0.2})
plt.plot([1,2,3,4],[1,4,9,16],’ro’)
Out[12]: [<matplotlib.lines.Line2D at 0x13920860>]
14.4.2. Cuadrícula
Otro elemento que puede agregar a una gráfica es una cuadrícula. A menudo, su
adición es necesaria para comprender mejor la posición que tiene cada punto en el
gráfico. Agregar una cuadrícula se puede hacer mediante a la función grid () con el
argumento True.
Ejemplo de gráfico con cuadrícula.
In [13]: plt.axis([0,5,0,20])
plt.title(’My first plot’,fontsize=20,fontname=’Times New Roman’)
plt.xlabel(’Counting’,color=’gray’)
plt.ylabel(’Square values’,color=’gray’)
plt.text(1,1.5,’First’)
plt.text(2,4.5,’Second’)
plt.text(3,9.5,’Third’)
plt.text(4,16.5,’Fourth’)
plt.text(1.1,12,r’$y = x^2$’,fontsize=20,
bbox={’facecolor’:’yellow’, ’alpha’:0.2})
plt.grid(True)
plt.plot([1,2,3,4],[1,4,9,16],’ro’)
Out[13]: [<matplotlib.lines.Line2D at 0x10f76898>]
14.4.3. Leyenda
Otro componente muy importante que debe estar presente en cualquier gráfico es
la leyenda. pyplot también proporciona la función legend() para añadir una leyenda
al gráfico y una cadena que indique las palabras con las que desea que se muestren las
series.
Por ejemplo, se asigna el nombre de “First series” a los datos gráficados.
In [14]: plt.axis([0,5,0,20])
plt.title(’My first plot’,fontsize=20,fontname=’Times New Roman’)
plt.xlabel(’Counting’,color=’gray’)
plt.ylabel(’Square values’,color=’gray’)
plt.text(2,4.5,’Second’)
plt.text(3,9.5,’Third’)
plt.text(4,16.5,’Fourth’)
plt.text(1.1,12,’$y =x^2$’,fontsize=20,bbox={’facecolor’:’yellow’,
’alpha’:0.2})
plt.grid(True)
plt.plot([1,2,3,4],[1,4,9,16],’ro’)
plt.legend([’First series’])
Out[14]: <matplotlib.legend.Legend at 0x16377550>
En el siguiente ejemplo, se gráfican varias series, cada una caracterizada por la función
plot() y el orden en que se definen corresponden al orden de las etiquetas de texto
definidas como argumento en la función legend ().
y = sin(3 ∗ x)/x
Matriz que contiene los valores de y: se puede obtener los valores de y, aplicando
la función np.sin() directamente a estos valores.
Finalmente, se realiza el gráfico con la función plot().
In [16]: import matplotlib.pyplot as plt
import numpy as np
x = np.arange(-2*np.pi,2*np.pi,0.01)
y = np.sin(3*x)/x
plt.plot(x,y)
Out[16]: [<matplotlib.lines.Line2D at 0x22404358>]
y = sin(n ∗ x)/x
14.5.3. Histogramas
Un histograma consiste en rectángulos adyacentes en el eje x, divididos en intervalos
discretos llamados "bins", y con un área proporcional a la frecuencia de las ocurren-
cias. Para representar un histograma, pyplot proporciona una función especial llamada
hist(). Esta función gráfica tiene una característica que otras funciones no tienen. La
función hist(), además de dibujar el histograma, devuelve una tupla de valores que son
los resultados del cálculo del histograma. La función hist() puede realizar el cálculo
del histograma, es decir, es suficiente con proporcionar una serie de muestras de valores
como argumento y el número de ubicaciones en las que se debe dividir, y la función se
encargará de dividir el rango de muestras en muchos intervalos, y luego se calculará las
ocurrencias para cada "bins".
Ejemplo: Se genera un array de 100 valores aleatorios de 0 a 100 usando la función
aleatoria randint(), y se divide en 20 "bins". Si no se especifica los "bins", el valor
predeterminado es 10.
Se tienen muchas opciones para para refinar más el gráfico de barras. Cada uno
de estos detalles se configuran añadiendo un kwarg específico como argumento en la
función bar().
Por ejemplo, se puede añadir los valores de la desviación estándar de la barra a través
del yerr kwarg junto con una lista que contenga las desviaciones estándar. Este kwarg
suele combinarse con otro kwarg llamado error_kw, que, a su vez, acepta otros kwarg
especializados para representar barras de error. Dos kwargs muy específicos utilizados
en este caso son eColor, que especifica el color de las barras de error, y capsize, que
define el ancho de las líneas transversales que marcan los extremos de las barras de error.
Otro kwarg que puede utilizar es el alfa, que indica el grado de transparencia de la
barra de color, alfa es un valor que va de 0 a 1. Cuando este valor es 0, el objeto es
completamente transparente para hacerse gradualmente más significativo con el aumento
del valor, hasta llegar a 1. Como de costumbre, se recomienda el uso de una leyenda,
por lo que en este caso se debe utilizar el kwarg legend() para identificar la serie que
se está representando.
Ejemplo de un gráfico de barras con barras de error.
In [23]: import numpy as np
index = np.arange(5)
values1 = [5,7,3,4,6]
std1 = [0.8,1,0.4,0.9,1.3]
plt.title(’A Bar Chart’)
plt.bar(index,values1,yerr=std1,error_kw={’ecolor’:’0.1’,
’capsize’:6},alpha=0.7,label=’First’)
plt.xticks(index+0.4,[’A’,’B’,’C’,’D’,’E’])
plt.legend(loc=2)
Como gráficos de líneas, los gráficos de barras también se utilizan generalmente para
mostrar simultáneamente series más grandes de valores. Pero en este caso es necesario
hacer algunas aclaraciones sobre cómo estructurar un gráfico de barras multiserie. En
este caso, se tiene varias barras que deben compartir la misma categoría. Un enfoque
utilizado para superar este problema es dividir el espacio ocupado por un índice (por
conveniencia su ancho es 1) en tantas partes como las barras que comparten ese índice
y, que queremos mostrar. Además, es aconsejable añadir espacio, que servirá para separar
una categoría con respecto a la siguiente.
Con respecto al gráfico de barras multiserie horizontal, el código es muy similar, solo
se debe reemplazar la función bar() por la correspondiente función barh() y no olvidar
reemplazar la función xticks() por la función yticks(). Es necesario invertir el rango
de valores que cubren los ejes en la función axis().
Ejemplo de gráfico de barras multiserie horizontal.
In [26]: import matplotlib.pyplot as plt
import numpy as np
index = np.arange(5)
values1 = [5,7,3,4,6]
values2 = [6,6,4,5,7]
values3 = [5,6,5,4,6]
bw = 0.3
plt.axis([0,8,0,5])
plt.title(’A Multiseries Horizontal Bar Chart’,fontsize=20)
plt.barh(index,values1,bw,color=’b’)
plt.barh(index+bw,values2,bw,color=’g’)
plt.barh(index+2*bw,values3,bw,color=’r’)
plt.yticks(index+0.4,[’A’,’B’,’C’,’D’,’E’])
Con respecto al gráfico de barras horizontal, se pueden aplicar las mismas reglas,
solo recuerde establecer barh() como el valor del tipo kwarg.
Después de hacer todos estos cambios, obtendrá el gráfico de barras horizontal api-
lado como se muestra a continuación, como ejemplo:
In [29]: import matplotlib.pyplot as plt
import numpy as np
index = np.arange(4)
series1 = np.array([3,4,5,3])
series2 = np.array([1,2,2,5])
series3 = np.array([2,3,3,4])
plt.axis([0,15,-0.5,3.5])
plt.title(’A Multiseries Horizontal Stacked Bar Chart’)
plt.barh(index,series1,color=’r’)
plt.barh(index,series2,color=’g’,left=series1)
plt.barh(index,series3,color=’b’,left=(series1+series2))
plt.yticks(index+0.4,[’Jan18’,’Feb18’,’Mar18’,’Apr18’])
Para añadir complejidad al gráfico circular, puede dibujarlo con una parte extraída del
pie. Para ello, existe un kwarg especial llamado explode. No es más que una secuencia
de valores de 0 o 1, donde 1 corresponde a la porción completamente extendida y 0
corresponde a las partes completas en el pie. También se puede ajustar el ángulo de
rotación de la figura añadiendo el kwarg: startangle, que toma un valor entero entre
0 y 360, que son los grados de rotación con precisión, donde 0 es el valor por defecto.
Ejemplo de gráfico pie con una parte de extraída.
In [34]: import matplotlib.pyplot as plt
labels = [’Nokia’,’Samsung’,’Apple’,’Lumia’]
values = [10,30,45,15]
colors = [’yellow’,’green’,’red’,’blue’]
explode = [0.3,0,0,0]
plt.title(’A Pie Chart’)
plt.pie(values,labels=labels,colors=colors,explode=explode,
startangle=180)
plt.axis(’equal’)
Además se puede utilizar el kwarg: autopct, que añade al centro de cada parte del
gráfico una etiqueta de texto que muestra el valor correspondiente. Finalmente, se puede
añadir una sombra el Kwarg: shadow configurandolo en True. Asi por ejemplo:
In [35]: import matplotlib.pyplot as plt
labels = [’Nokia’,’Samsung’,’Apple’,’Lumia’]
values = [10,30,45,15]
colors = [’yellow’,’green’,’red’,’blue’]
explode = [0.3,0,0,0]
plt.title(’A Pie Chart’)
plt.pie(values,labels=labels,colors=colors,explode=explode,
shadow=True,autopct=’ %1.1f % %’,startangle=180)
plt.axis(’equal’)
Este es un gráfico que tiene características tanto del gráfico circular como del gráfico
de barras. De hecho, como el gráfico circular, el ángulo de cada sector da información
porcentual representada por esa categoría con respecto al total. En cuanto al gráfico de
barras, el gráfico radial es el valor numérico de esa categoría.
6
Para mayor detalle revisar:
https://matplotlib.org/tutorials/index.html
https://pypi.org/project/jupyter-plotly-dash/
Para obtener un gráfico polar se debe usar la función bar() e indicar la lista que
contiene los ángulos θ y una lista de la extensión radial de cada sector.
Es importante recordar, que se puede definir el color del gráfico con una lista de
valores de cadena que contengan códigos RGB en el formato #rrggbb correspondientes
a los colores que se deseen.
14.6. Gráficos 3D
El módulo mplot3d usa también el objeto Figure, sólo que en lugar de los ejes definirá
un nuevo tipo de objeto, llamado Axes3D. Por lo tanto, es necesario importar este módulo
para usar el objeto Axes3D.
from mpl_toolkits.mplot3d import Axes3D
14.6.1. Superficies 3D
Con el paquete mplot3D, las superficies se pueden dibujar directamente en 3D. Por
ejemplo, se gráfica la función z = f (x, y), y se puede ver la superficie con la función
plot_surface().
In [39]: from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-2,2,0.1)
Y = np.arange(-2,2,0.1)
X,Y = np.meshgrid(X,Y)
def f(x,y):
return (1 - y**5 + x**5)*np.exp(-x**2-y**2)
ax.plot_surface(X,Y,f(X,Y), rstride=1, cstride=1)
Una superficie 3D se destaca más al cambiar el mapa de color, por ejemplo, se puede
establecer la opción kwarg cmap. También se puede rotar la superficie usando la función
view_init(). De hecho, este ajusta el punto de vista desde el que se ve la superficie,
cambiando los kwargs: elev y azim. A través de su combinación se puede obtener la
superficie mostrada desde cualquier ángulo. El primer kwarg ajusta la altura a la que se
ve la superficie, mientras que el segundo ajusta el ángulo de rotación de la superficie.
A continuación un ejemplo.
In [40]: from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
fig = plt.figure()
ax = Axes3D(fig)
X = np.arange(-2,2,0.1)
Y = np.arange(-2,2,0.1)
X,Y = np.meshgrid(X,Y)
def f(x,y): return (1 - y**5 + x**5)*np.exp(-x**2-y**2)
ax.plot_surface(X,Y,f(X,Y), rstride=1, cstride=1, cmap=plt.cm.hot)
ax.view_init(elev=30,azim=125)
ax.bar(x,y,0,zdir=’y’,color=clr)
ax.bar(x,y2,10,zdir=’y’,color=clr)
ax.bar(x,y3,20,zdir=’y’,color=clr)
ax.bar(x,y4,30,zdir=’y’,color=clr)
ax.bar(x,y5,40,zdir=’y’,color=clr)
ax.set_xlabel(’X Axis’)
ax.set_ylabel(’Y Axis’)
ax.set_zlabel(’Z Axis’)
ax.view_init(elev=40)
Tools
Time Series analysis tsa
The Datasets Package
7
Para mayor detalle ver https://www.statsmodels.org/stable/
1. Estadísticas descriptivas
Este paquete tiene un conjunto funciones para las estadísticas descriptivas, co-
mo parte de la exploración de datos. A continuación se tiene un listado de las
principales funciones:
Funciones Descripción
stattools.acovf(x[, unbiased, demean, fft, . . . ]) Autocovarianza para 1D
stattools.acf(x[, unbiased, nlags, qstat, . . . ]) Función de autocorrelación para arreglos 1d.
stattools.pacf(x[, nlags, method, alpha]) Autocorrelación parcial estimada
stattools.pacf_ols(x[, nlags, efficient, . . . ]) Calcular autocorrelaciones parciales mediante
OLS
stattools.ccf(x, y[, unbiased]) función de correlación cruzada para 1d
stattools.periodogram(X) Devuelve el periodograma para la frecuencia
natural de X
stattools.adfuller(x[, maxlag, regression, . . . ]) Prueba de raíz de la unidad Dickey-Fuller
aumentada
stattools.kpss(x[, regression, lags, store]) Prueba de estacionariedad de
Kwiatkowski-Phillips-Schmidt-Shin
stattools.coint(y0, y1[, trend, method, . . . ]) Prueba de no cointegración de una ecuación
univariada
stattools.q_stat(x, nobs[, type]) Estadística de Return’s Ljung-Box Q
stattools.levinson_durbin(s[, nlags, isacov]) Recursividad de Levinson-Durbin para
procesos autorregresivos
stattools.innovations_algo(acov[, nobs, rtol]) Algoritmo de innovaciones para convertir
autocovarianzas a parámetros MA
stattools.levinson_durbin_pacf(pacf[, nlags]) Algoritmo Levinson-Durbin que devuelve los
coeficientes acf y ar
stattools.arma_order_select_ic(y[, max_ar, . . . ]) Devuelve los criterios de información para
muchos modelos ARMA
2. Interpolación
statsmodels.tsa.interp.denton.dentonm es un método que se usa para con-
vertir datos de baja frecuencia a alta frecuencia. El método de Denton minimiza
la distancia dada por la función de penalización, con de mínimos cuadrados, entre
la serie de referencia desconocida y la serie de indicadores sujeta a la condición
de que la suma de la serie de referencia sea igual a la referencia. Si no se dispone
de ningún punto de referencia para las últimas observaciones de los indicadores,
la extrapolación se realiza utilizando el último ratio indicador de referencia del
período anterior.
Matemáticamente se tiene:
Minimiza la suma
sum(X) = A
Ejemplo:
indicator = [50,100,150,100] * 5
benchmark = [500,400,300,400,500]
benchmarked = dentonm(indicator, benchmark, freq="aq")
4. statsmodels.multivariate.pca.PCA
Este módulo de Análisis de componentes principales tiene los siguientes paráme-
tros:
Ejemplo
Métodos Descripción
plot_rsquare([ncomp, ax]) Gráficos de caja de la serie individual
R-cuadrado contra el número de PCs
plot_scree([ncomp, log_scale, cumulative, ax]) Diagrama de los valores propios
ordenados
project([ncomp, transform, unweight]) Serie de proyectos en un número
específico de factores
5. Gráficos
A continuación se tiene un resumen de las principales funciones del paquete stat-
models, para realziar distintos tipos de gráficos.
a) Bondad de ajuste
Métodos Descripción
gofplots.qqplot(data[, dist, distargs, a, . . . ]) Gráfico Q-Q de los cuantiles de x
frente a los cuantiles/ppf de una
distribución
gofplots.qqline(ax, line[, x, y, dist, fmt]) Traza una línea de referencia para un
qqplot.
gofplots.qqplot_2samples(data1, data2[, . . . ]) Q-Q Gráfico de los cuantiles de dos
muestras.
gofplots.ProbPlot(data[, dist, fit, . . . ]) Clase para la construcción
conveniente de gráficos Q-Q, P-P y
de probabilidad.
b) Boxplots
Métodos Descripción
boxplots.violinplot(data[, ax, labels, . . . ]) Gráfica de violín de cada conjunto de datos en
la secuencia de datos.
boxplots.beanplot(data[, ax, labels, . . . ]) Gráfica bean de cada conjunto de datos en la
secuencia de datos.
c) Gráficos de correlación
Métodos Descripción
correlation.plot_corr(dcorr[, xnames, . . . ]) Trazar la correlación de muchas variables en
una cuadrícula de colores ajustada.
correlation.plot_corr_grid(dcorrs[, titles, . . . ]) Cree una tabla de gráficos de correlación.
plot_grids.scatter_ellipse(data[, level, . . . ]) Crea una cuadrícula de gráficos de
dispersión con elipses de confianza.
d) Gráficos funcionales
Métodos Descripción
functional.hdrboxplot(data[, ncomp, alpha, . . . ]) Boxplot de la región de alta densidad
functional.fboxplot(data[, xdata, labels, . . . ]) Gráfico funcional.
functional.rainbowplot(data[, xdata, depth, . . . ]) Crea una trama de arco iris para un
conjunto de curvas.
functional.banddepth(data[, method]) Calcular la profundidad de la banda para
un conjunto de curvas funcionales.
e) Gráficos de regresión
Métodos Descripción
regressionplots.plot_fit(results, exog_idx) Gráfica de ajuste de regresión
regressionplots.plot_regress_exog(results, . . . ) Grafica los resultados de regresión contra un
regresor.
regressionplots.plot_partregress(endog, . . . ) Gráfica de regresión parcial para un solo
regresor
regressionplots.plot_partregress_grid(results) Gráfica de regresión parcial para un
conjunto de regresores.
regressionplots.plot_ccpr(results, exog_idx) CCPR contra un regresor.
regressionplots.plot_ccpr_grid(results[, . . . ]) Generar gráficas del CCPR contra un
conjunto de regresores, gráficas en
cuadrícula.
regressionplots.plot_ceres_residuals(. . . [, . . . ]) Produce un gráfico CERES (Conditional
Expectation Partial Residuals) para un
modelo de regresión ajustado.
regressionplots.abline_plot([intercept, . . . ]) Traza una línea dada una intercepción y una
pendiente.
regressionplots.influence_plot(results[, . . . ]) Trama de influencia en la regresión.
regressionplots.plot_leverage_resid2(results) Estadísticas de apalancamiento de gráficos.
Métodos Descripción
tsaplots.plot_acf(x[, ax, lags, alpha, . . . ]) Trazar la función de autocorrelación
tsaplots.plot_pacf(x[, ax, lags, alpha, . . . ]) Trazar la función de autocorrelación parcial
tsaplots.month_plot(x[, dates, ylabel, ax]) Gráfico estacional de los datos mensuales
tsaplots.quarter_plot(x[, dates, ylabel, ax]) Gráfico estacional de los datos trimestrales
g) Otros gráficos
Métodos Descripción
factorplots.interaction_plot(x, trace, response) Gráfico de interacción para
estadísticas de nivel de factor.
mosaicplot.mosaic(data[, index, ax, . . . ]) Crea una gráfica de mosaico a partir
de una tabla de contingencia.
agreement.mean_diff_plot(m1, m2[, sd_limit, . . . ]) Gráfico de diferencia de medias.
2. Cambiar el directorio
$ cd wealth-viz
3. Instalar el paquete
$ python setup.py install
1. El método blotter.
Referencias
[1] H. Bhasin. Python Basics A Self-Teaching Introduction. Mercury, 2019.
[2] David Jamieson Bolder. Credit-Risk Modelling: Theoretical Foundations, Diagnostic
Tools, Practical Examples, and Numerical Recipes in Python. Springer International
Publishing, 1st ed. edition, 2018.
[3] Claus Fuher. Computing With Python: An Introduction to Python for Science &
Engineering. Pearson Education Limited, 2013.
[4] Alex Galea. Applied Data Science with Python and Jupyter. Packt Publishing,
2018.
[5] Veena A. Gowrishankar S. Introduction to Python Programming. CRC, 2019.
[6] Magnus Lie Hetland. Beginning Python: From Novice to Professional. Apress, 3rd
ed. edition, 2017.
[7] Michael Heydt. Mastering pandas for Finance: Master pandas, an open source
Python Data Analysis Library, for financial data analysis. Packt Publishing, 2015.
[8] Yves Hilpisch. Derivatives Analytics with Python: Data Analysis, Models, Simula-
tion, Calibration and Hedging. Wiley, 2015.
[9] Yves Hilpisch. Python for Finance: Mastering Data-Driven Finance. O’Reilly Media,
2nd edition, 2019.
[10] Yves J Hilpisch. Python for Finance: Analyze Big Financial Data. O’Reilly Media,
first edition edition, 2015.
[11] Pawel Lachowicz. Python for Quants, volume 1. QuantAtRisk, 2015.
[12] Eric Matthes. Python Crash Course A Hands-On, Project-Based Introduction to
Programming. No Starch Press, 2016.
[13] Bhaskar N. Das Mohit. Learn Python in 7 days : get up-and-running with Python.
Packt Publishing - ebooks Account, 2017.
[14] Fabio Nelli. Python Data Analytics with Pandas, NumPy and Matplotlib [2nd ed.].
Apress, 2018.
[15] Ajay Ohri. Python for R users : a data science approach. Wiley, 2018.
[16] David J. Pine. Introduction to Python for Science and Engineering. Series in
Computational Physics. CRC Press, 2019.
[17] Christopher Gardner Shayne Fletcher. Financial Modelling in Python (The Wiley
Finance Series). Wiley, 2009.
[18] Ben Stephenson. The Python Workbook: A Brief Introduction with Exercises and
Solutions. Texts in Computer Science. Springer, 2 edition, 2019-08.
[19] James Ma Weiming. Mastering Python for Finance. Packt Publishing, 2015.
[20] Yuxing Yan. Python for Finance. Packt Publishing, 2nd edition, 2017.