Entornos virtuales - conda vs. pipenv

Idealmente todo el código se ejecuta dentro de un entorno aislado del resto de los programas y aplicaciones instalados en tu computadora, evitando así que existan conflictos entre dependencias. Esto nos ayuda a dos cosas: nos facilita la vida evitando conflictos entre dependencias y, lo más importante en la ciencia de datos, ayuda en la reproducibilidad de nuestros experimentos y análisis.

He hablado sobre entornos virtuales en el pasado: un video sobre ellos y un directo también.

En el mundo científico-pythonista el gestor de entornos y paquetes por excelencia es Conda; sin embargo yo tengo una preferencia personal por Pipenv pues es más ligero, minimalista y completamente enfocado en Python. Potatos, potatoes cualquier gestor de paquetes que decidas usar es bueno.

Docker: Puedes ejecutar estos notebooks en un contenedor de Docker también.

Paquetes

(Entre las primeras cosas que mencionaré en cada uno de los notebooks estará una sección llamada "Paquetes" en la cual listaré los paquetes que vamos a usar durante la sesión, esta información es solo como referencia, los paquetes ya deberían estar instalados si instalaste los requerimientos correctamente desde el inicio)

  • jupyterlab
  • matplotlib
  • ipympl
  • numpy

(Dependiendo del gestor de paquetes que uses tendrás que instalarlos manualmente, por ejemplo pipenv install jupyterlab instala jupyterlab usando pipenv)

Qué es Jupyter Lab

Jupyter Lab es la nueva interfaz gráfica que nos permite interactuar con los Jupyter Notebooks. Estos notebooks son una versión mas ... para interactuar con la consola de Python. Cada notebook tiene asociada una consola de Python (también conocido como kernel) que está activa y esperando a que nosotros le mandemos comandos usando la interfaz gráfica de nuestros notebooks.

Las Notebooks son una implementación del paradigma de programación letrada ideado por Donald Knuth. Esto se logra mediante el uso de celdas (cells) en donde cada una de estas celdas puede ser de dos tipos: texto escrito con markdown o código que en este caso vamos a escribir en Python.

Tecnicalidades

Jupyter funciona con una arquitectura cliente-servidor, lo que ustedes están viendo en esta pantalla es el cliente reperesentado por una aplicación web y el servidor es una aplicación que se está ejecutando en su computadora. Esto significa que podríamos tener el servidor de Jupyter ejecutándose en una computadora más poderosa (por ejemplo, en AWS) y nosotros poder acceder desde cualquier navegador y programar desde ahí. A pesar de esto también es muy común tener cliente y servidor en la misma computadora.

Otros kernels: Es posible configurar nuestro servidor de Jupyter para que acepte otros kernels de disntintos lenguajes o distintas versiones de Python, entre ellos Julia, R y hasta C#.

Ventajas

  • Son perfectos para mostrar tu trabajo
  • Facilitan la experimentación
  • Tienen una curva de aprendizaje relativamente baja
  • Su arquitectura las hace ideales para uso remoto

Desventajas

  • Es fácil escribir código espagueti
  • No es tan sencillo colaborar en el mismo notebook
  • Sin todas las herramientas de un IDE
  • Dificultad a la hora de depurar

El funcionamiento de las notebooks se centra en una entidad conocida como "celda", a nosotros nos interesan dos tipos de celdas: de código y de markdown, ésta y todas las celdas anteriores son celdas de markdown.

  • Doble click (o Enter) en una celda para entrar en modo de edición
  • Esc para salir de modo de edición y entrar en modo comandos
  • Ctrl + Enter ejecuta la celda actual (y permanece en esta)
  • Shift + Enter ejecuta la celda actual y avanza a la siguiente
  • Alt + Enter ejecuta la celda actual y crea una nueva justo debajo de la actual
  • En modo comandos:
    • y para navegar entre celdas
    • M para cambiar una celda a markdown
    • Y para cambiar una celda a código
    • D + D para eliminar una celda
    • Z para deshacer cambios a las celdas
    • A agrega una celda arriba de la actual
    • B agrega una celda debajo de la actual

"!" en las celdas

Puedes poner un ! como prefijo para indicarle al intérprete que el código a ejecutar después del i no es un comando para python, sino algo que debe ejecutar en la terminal del sistema operativo del host:

!echo "Hola!"
Hola!
# Podemos combinar comentarios y comandos de consola...
!echo "import jupyterlab; print(jupyterlab.__version__)" > temporary.py
# ¡Podemos combinar Python y comandos de consola!
for i in range(2):
    resultado_consola = !echo "Hello $i"
    print(resultado_consola)
['Hello 0']
['Hello 1']

"?" en las celdas

Podemos usar el símbolo "?" para obtener ayuda sobre el código en Python, podemos poner el símbolo antes o después de la instrucción sobre la que queremos saber más.

?str
list?

Comandos mágicos (?)

En adición a los signos anteriores, dentro de las celdas de las notebooks también podemos usar elementos conocidos como "comandos mágicos" que son atajos a funciones útiles.

Ejecutar un script

# Ejecutando un script de python con %run
%run temporary.py
/Users/antonioferegrino/.local/share/virtualenvs/df-JhqtXTwc/lib/python3.8/site-packages/jupyter_server/transutils.py:13: FutureWarning: The alias `_()` will be deprecated. Use `_i18n()` instead.
  warnings.warn(warn_msg, FutureWarning)


3.0.12

Cargar un script

# %load temporary.py
import jupyterlab

print(jupyterlab.__version__)
3.0.12

Cronómetrando nuestro código

Siempre es bueno tener una idea de cuánto tiempo es que nuestro código se va a tardar en ejecutar, podemos usar dos formas de medir el tiempo con los comandos mágicos:

  • %%time: para calcular el tiempo que tarda una celda completa en ejecutarse
  • %timeit: para calcular el tiempo de ejecución de una línea de código (ejecuta la línea múltiples veces para analizar el resultado:
%%time
import time
for i in range(4):
    time.sleep(i)
print("done")
done
CPU times: user 1.36 ms, sys: 1.39 ms, total: 2.75 ms
Wall time: 6 s
import random

# %timeit random.randint(10, 15)
%timeit -n 10 random.randint(10, 15)
1.39 µs ± 609 ns per loop (mean ± std. dev. of 7 runs, 10 loops each)

Gráficando en las notebooks

Una de las grandes ventajas que tenemos con las notebooks es que podemos crear gráficas dentro de ellas, mientras que podemos emplear el módulo matplotlib, podemos también cambiar el backend que estamos usando para graficar; por default el backend es inline, pero gracias a ipympl podemos tener gráficas interactivas si cambiamos el backend a widget con el comando mágico %matplotlib widget

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
# %config InlineBackend.figure_format ='retina'

fig = plt.figure()
plt.plot(np.sin(np.linspace(0, 20, 100)));
[<matplotlib.lines.Line2D at 0x11f41b970>]

png

%matplotlib widget

fig = plt.figure()
plt.plot(np.sin(np.linspace(0, 20, 100)));
Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …





[<matplotlib.lines.Line2D at 0x11f60dc70>]

🚨 Es importante mencionar que tanto "!", "?" y "%" son elementos disponibles en los Juypyter Notebooks, de ninguna manera pertenecen a la sintaxis del lenguaje Python.

Bonus: \(\mu\alpha\tau\epsilon\mu\alpha\tau\iota\kappa\alpha\sigma\)

Además de markdown las celdas de las notebooks permiten usar símbolos matemáticos, mediante el uso del símbolo $, hay dos formas de hacerlo

  • En línea: Tenemos que colocar la expresión matemática entre $; ejemplo $e = m \times c^2$ se verá así: \(e = m \times c^2\)
  • En bloque: Tenemos que colocar la expresión matemática entre $$; ejemplo $$e = m \times c^2$$ se verá así: \(e = m \times c^2\)

En lecciones subsecuentes vamos a ver algunas fórmulas 🧐

Playground


Referencias

Sitios web