Python para Análisis de datos: Introducción

Sesión 1

Jesús Fernández (fernandez.cuesta@gmail.com)

1 Abril 2019

Introducción a Python

Introducción a Python

Python_logo_1990s

Creado en 1990 por Guido van Rossum

Guido van Rossum, 1999
Guido van Rossum, 1999

Definición y evolución del lenguaje recogido en PEPs (Python Enhancement Proposals)

  • Énfasis en la productividad y legibilidad del código (PEP20)
    • Beautiful is better than ugly
    • Explicit is better than implicit
    • Simple is better than complex
    • Complex is better than complicated
    • Readability counts
  • +reusable, +fácil mantener

Ejemplo:

  • Actualmente dos versiones principales activas:
    • Python 2.7 (soporte hasta 1/1/2020)
    • Python 3.x (3.6, 3.7)
python x.y.z
x: versión principal, incompatibles entre sí [2, 3]
y: versión secundaria, normalmente compatibles
z: versión menor (errores y seguridad)

timeline
Línea temporal de versiones, en rojo: versión obsoleta

  • Lenguaje de alto nivel, interpretado, orientado a objetos
  • Alta productividad, no compilado
  • Gran cantidad de librerías incorporadas (batteries included)
  • + librerías externas (>1M): Python Package Index (PyPI)

Alto nivel

Código ejemplo en C++

Equivalente python

Interpretado

  • No es necesario compilar…

    exec_compiler

    exec_interpreter

    … pero necesitamos tener instalado un intérprete python.exe

Interpretado

  • Compatible (en general) entre distintos sistemas operativos y arquitecturas:
    • Linux
    • MacOS
    • Windows
    • otros (AIX, AS/400, z/OS, OpenVMS, ARM, …)
    • Arduino/Raspberry PI (IoT)
  • Depuración de errores desde intérprete
  • Gestión automática de memoria

Práctica

intérprete python

  • Anaconda Prompt > python (> ipython)

    interprete

Diferentes paradigmas de programación

  • Orientado a objetos
  • Procedural
  • Imperativo
  • Funcional (<100%)

Python es usado en

Data Science

  

Machine Learning

  

Desarrollo Web

(p.e. pinterest, instagram, linkedin, …)

  

Desarrollo software (scripts, prototipos, …)

como “pegamento” entre componentes escritos en otros lenguajes

  logo_sqlalchemy

Automatización de procesos software

simpson

Automatización de procesos software

  

Python como lenguaje de programación

The 2018 Top Programming Languages, IEEE

ieee_graph

gran soporte en foros, comunidades, conferencias, …

stackoverflow

stackoverflow_top

Worldwide, Python is the most popular language, Python grew the most in the last 5 years (PYPL)

R vs Python

stackoverflow_graph
fuente: stackoverflow

  • R: muy enfocado en análisis estadístico
  • Python: generalista, con librerías especializadas (pandas, scikit-learn, scipy, … )

¿?

Guido van Rossum, 1995
Guido van Rossum, 1995

Instalación y entorno

Instalación y entorno de programación

Diferentes distribuciones para Windows:

Podemos ejecutar código python:

  • Directamente (si el S.O. lo permite, #!)
  • Desde un intérprete interactivo python (p.e. ipython, bpython)
  • Desde un cuaderno jupyter

  • Para ejecutar código python necesitaremos un intérprete (python.exe).
  • Preinstalado en ciertos S.O. (p.e. Linux, Mac OS X)
  • Diferentes tipos de intérprete (CPython, PyPy, Jython, IronPython…)
  • Podemos tener “n” intérpretes distintos instalados en el sistema, cada uno con diferentes librerías
  • conda: instala por defecto un entorno (intérprete) base y un conjunto de librerías

hierarchy

Cada entorno tiene un único intérprete python + librerías

entornos

entornos_brokendeps

  • … necesitamos un entorno independiente

https://xkcd.com/1987
https://xkcd.com/1987

¿Solución?

Entornos virtuales

Entornos virtuales

  • Funcionan como un marco aislado y seguro
  • Independientes entre sí
  • Permiten especificar versiones de Python (2.7.10, 3.6.6, 3.6.7, …)
  • Facilmente reproducibles y exportables (Portabilidad)
    • p.e. replicar un entorno preexistente
  • De “usar y tirar” (p.e. probar nuevas versiones de código o librerías)

Por defecto partiremos de un entorno global/base entornos

Regla general: evitar usar el intérprete global del sistema y el entorno base

  • Puede afectar a otros componentes
  • Dependencias entre distintos proyectos
  • Puede no ser la misma versión que la requerida en un proyecto

entornos_venv

entornos_conda

Conda

Python en Windows

Conda (anaconda/miniconda)

  • Gestor de paquetes multi-lenguaje (python/R/…)
  • Transparente: no instala ficheros fuera de su directorio
  • Distribución multipropósito, gestiona paquetes adicionales (p.e. git, librerías, …)
  • Coexistencia de entornos con diferentes librerías y versiones de python
  • Por defecto nos encontraremos en un entorno llamado base

Anaconda Miniconda
~3GB disco <400MB
> 200 librerías base + dependencias
+ herramientas ciclo distribución +rápido
IDE (Spyder + VSCode)
Anaconda Navigator sin interfaz gráfico
↑ tiempo instalación

Alternativas (más bajo nivel):

Determinar la plataforma sobre la que se va a instalar

conda_platform

https://www.anaconda.com/download/ setup
con chocolatey:

🕐 7-15 minutos

Práctica I

Práctica I

Entorno virtual con Navigator

  • Ejecutar “Anaconda Navigator” y crear un nuevo entorno (distinto a base) con diferentes librerías instaladas, p.e.:
pandas beautifulsoup4
requests jupyter
scrapy matplotlib
sqlalchemy numpy
jsonschema seaborn

Práctica II

Práctica II: Entorno virtual en modo texto

Entorno virtual en modo texto

  • Ejecutar Anaconda prompt o acceder a la terminal desde vscode
  • Verificar que conda está instalado:

Crear un entorno virtual con pandas, scrapy, jupyter, bs4 y pyjstat.

  • Inicializar el entorno virtual. Ejemplos:
  • Acceder (activar) el entorno virtual:

Crear un entorno virtual con pandas, scrapy, jupyter, bs4 y pyjstat.

  • Exportar entorno virtual (distribuible y replicable)
  • Acceder al entorno virtual y mostrar librerías instaladas

vscode

Visual Studio Code

  • Paleta de comandos (Ctrl+Shift+P)
    • “Instalar extensiones”
    • “Python: …”

vscode_screenshot

Integración con el entorno virtual de cada proyecto

  • Seleccionar intérprete + nombre del entorno
  • terminal > ipython / python o bien “Python: ejecutar REPL”

Linter

  • Analizador del código, detecta errores de sintaxis, estilo, …
  • Necesario instalar en cada entorno (preinstalado en base)
    • Paleta de comandos > Python: seleccionar Linter > flake8

flake8

  • Comprueba conformidad con PEP8, complejidad de McCabe, errores de sintaxis…
  • Permite ignorar/silenciar diferentes avisos, excluir ficheros del análisis, …

Depuración de errores

  • Errores de sintaxis
  • Avisos del linter

Estructura del código

Estructura del código

  • No hay delimitadores de línea (tipo ‘;’)
  • Jerarquía del código según nivel de indentación
  • Indentar código con espacios
  • Comentar código con « # »
  • Importar librerías al inicio
  • Código agrupado con líneas en blanco
  • Recomendado: Longitud de línea < 80 caracteres

cuaderno jupyter

cuaderno jupyter (offline)

  • Importar librerías al inicio
  • Código agrupado con líneas en blanco
    • 2 líneas después de los import
    • funciones y clases: 2 líneas antes/después
    • métodos dentro de clases: 1 línea
    • líneas adicionales para agrupar funciones relacionadas

Palabras reservadas

import builtins
import keyword


print(', '.join(keyword.kwlist))
False, None, True, and, as, assert, async, await, break, class,
continue, def, del, elif, else, except, finally, for, from,
global, if, import, in, is, lambda, nonlocal, not, or, pass,
raise, return, try, while, with, yield

print(dir(builtins))
['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
'FileExistsError', 'FileNotFoundError', 'FloatingPointError', 'FutureWarning',
'GeneratorExit', 'IOError', 'ImportError', 'ImportWarning', 'IndentationError',
'IndexError', 'InterruptedError', 'IsADirectoryError', 'KeyError',
'KeyboardInterrupt', 'LookupError', 'MemoryError', 'ModuleNotFoundError',
'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
'NotImplementedError', 'OSError', 'OverflowError', 'PendingDeprecationWarning',
'PermissionError', 'ProcessLookupError', 'RecursionError', 'ReferenceError',
'ResourceWarning', 'RuntimeError', 'RuntimeWarning', 'StopAsyncIteration',
'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError', 'SystemExit',
'TabError', 'TimeoutError', 'True', 'TypeError', 'UnboundLocalError',
'UnicodeDecodeError', 'UnicodeEncodeError', 'UnicodeError',
'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning', 'ValueError',
'Warning', 'ZeroDivisionError', '__IPYTHON__', '__build_class__', '__debug__',
'__doc__', '__import__', '__loader__', '__name__', '__package__', '__spec__',
'abs', 'all', 'any', 'ascii', 'bin', 'bool', 'breakpoint', 'bytearray',
'bytes', 'callable', 'chr', 'classmethod', 'compile', 'complex', 'copyright',
'credits', 'delattr', 'dict', 'dir', 'display', 'divmod', 'enumerate', 'eval',
'exec', 'filter', 'float', 'format', 'frozenset', 'get_ipython', 'getattr',
'globals', 'hasattr', 'hash', 'help', 'hex', 'id', 'input', 'int',
'isinstance', 'issubclass', 'iter', 'len', 'license', 'list', 'locals', 'map',
'max', 'memoryview', 'min', 'next', 'object', 'oct', 'open', 'ord', 'pow',
'print', 'property', 'range', 'repr', 'reversed', 'round', 'set', 'setattr',
'slice', 'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type',
'vars', 'zip']

if __name__ == "__main__":

  • Un fichero python puede contener (entre otros) definiciones de constantes, variables, funciones o clases.
  • Para organizar el código guardaremos los ficheros .py en un árbol de directorios:
    principal/
        __init__.py         import principal
        practica.py
        recolector/         from principal import recolector
            __init__.py
            collector.py
            database.py
        conversor/
            __init__.py
            limpia.py
            procesa.py
        graficos/
            __init__.py
            graficos.py
            exportar.py
        string/
            __init__.py
            string.py

Proyecto ejemplo

proyecto/
    README.rst
    LICENSE
    setup.py
    requirements.txt
    entorno_conda.yml
    ejemplo/__init__.py
    ejemplo/core.py
    ejemplo/helpers.py
    docs/conf.py
    docs/index.rst
    tests/unitarios.py
    tests/funcionales.py
nombre del paquete
descripción del proyecto
licencia [2]
distribución/empaquetado [3]
descripción de las dependencias
descripción del entorno
el código en sí
" "
" "
documentación del proyecto
" "
funciones de test del proyecto
" "

³ p.e. setuptools

Cómo importar módulos

Código estructurado por módulos/submódulos

    principal/
        __init__.py  <-------- entrada al módulo principal
        recolector/       <-----.
            __init__.py         |
            collector.py --.    |
            database.py    |    |
        conversor/   <-----'    |
            __init__.py         |
            limpia.py ----------'
            procesa.py
  • Dependencias cíclicas: método de collector.py necesita importar conversor, mientras que limpia.py importa recolector
  • Acoplamiento: cambios en conversor afectan a recolector
  • Uso excesivo de variables globales
  • Anidamiento excesivo (búcles for, if)
  • Defecto/exceso de clases (stop writing classes)

Práctica III

Práctica III: Consola ipython

Parte 1

  • Abrir una consola ipython
  • In[n] identifica las entradas de comandos
  • comandos mágicos (solamente para ipython)
    • comienzan por el caracter ‘%
    • ejemplo: %run, %matplotlib, %load, %who
  • Ctrl+R activa la búsqueda en el historial
    • %hist, %history para visualizarlo
  • _ guarda la salida del último comando &sup4;

&sup4; _ se usa también como variable de usar/tirar, p.e. cuando una función devuelve varios resultados, pero solamente estamos interesados en uno.

  • [TAB] autocompleta (p.e. import st[TAB])
    • muy útil para ver los métodos/atributos de un módulo/clase

Ejemplos

  • Importa la librería math
  • Convierte 67 grados a radianes (math.radians)
  • Calcula el cuadrado (n²) del resultado (operador ** o math.pow)
  • Verifica si el resultado es mayor que 16/13

Solución

Parte 2

  • Importa la librería numpy
    • import numpy as np
  • Importa el módulo pyplot de la librería matplotlib
    • from matplotlib import pyplot as plt
  • Crea un array a de 1000 puntos entre [0, 1]
    • Ejecuta el método np.linspace()
  • Calcula el seno de 2 ⋅ π ⋅ a
    • usa el método np.sin()
    • usa la constante np.pi
  • Activa el modo gráfico integrado
    • %matplotlib inline
  • Crea un gráfico con a en el eje x y 2 ⋅ π ⋅ a en el eje y
    • emplea la función plt.plot()

:::

Solución

Práctica IV

Práctica IV: Ejecutar un cuaderno jupyter

Descargar el cuaderno de ejemplo en el directorio python y ejecutar línea por línea.

(o bien ejecutarlo en forma remota con Binder)

Práctica V

Práctica V: Exportar e importar un entorno virtual

Exportar entorno virtual (II)
  • Copia y restauración de dependencias con pip (requirements.txt)
    • independiente de conda

Recursos adicionales

Recursos adicionales

python_documentation Documentación oficial

Otros recursos en línea

Bonus: pipenv

Bonus: pipenv

  • Permite gestionar un entorno virtual y sus dependencias
  • Instalación desde pip
  • Cada carpeta de proyecto es considerada un entorno virtual
  • Pipfile y Pipfile.lock definen las dependencias
    • Pipfile.lock para versiones específicas, evitando que se actualicen
    • Recomendable añadir ambos ficheros en control de versiones
  • Ejecutar scripts con pipenv run ...

Instala pipenv y crea un entorno virtual nuevo

Instala distintos paquetes dentro del entorno virtual

Para comprobar los paquetes instalados, mostrar el contenido de Pipfile

Otras funcionalidades útiles con pipenv:

Acceder al intérprete propio del entorno:

Ejecutar código cargando librerías propias del entorno:

Restaura un entorno virtual desde los ficheros Pipfile y Pipfile.lock:

Bonus (II): GIL y GC

Bonus (II): GIL y GC

Reference counting

  • Usado por python para la gestión de memoria
  • Cuenta las referencias a cada objeto creado
  • Cuando la cuenta es 0, la memoria reservada se libera

GC: Garbage Collector

Utiliza 2 algoritmos para la gestión de memoria:

  • Reference counting: libera objetos sin referencias en un programa
    • ejecutado en “tiempo real”
  • Referencias cíclicas: se ejecuta periódicamente

Ejemplo

GIL: Global Interpreter Lock

  • Afecta a CPython
  • Evita que la variable de conteo de referencias entre en condición de carrera
  • Restringe la ejecución de código concurrente
    • ejecución secuencial dentro del intérprete
    • multithreading: aplicaciones no limitadas por CPU (p.e. I/O)
    • multiprocessing: varios intérpretes concurrentemente

GIL

Ejemplo práctico: programa limitado por CPU, ejecución secuencial

Programa limitado por CPU, ejecución concurrente (multithread)

Programa limitado por CPU, ejecución concurrente (multiprocess)

cuaderno jupyter (offline)

cuaderno jupyter (binder)