tutorial notebook lab examples python refactoring ipython-notebook readability jupyter

notebook - jupyter python 3



Las mejores prácticas para convertir los cuadernos jupyter en scripts de python (2)

Ahorro de vida : a medida que escribes tus cuadernos, refactoriza gradualmente tu código en funciones, escribiendo algunas pruebas y docstrings mínimos.

Después de eso, refactorizar de cuaderno a script es natural. No solo eso, sino que te hace la vida más fácil cuando escribes cuadernos largos, incluso si no tienes planes de convertirlos en otra cosa.

Ejemplo básico del contenido de una celda con pruebas "mínimas" y docstrings:

def zip_count(f): """Given zip filename, returns number of files inside. str -> int""" from contextlib import closing with closing(zipfile.ZipFile(f)) as archive: num_files = len(archive.infolist()) return num_files zip_filename = ''data/myfile.zip'' # Make sure `myfile` always has three files assert zip_count(zip_filename) == 3 # And total zip size is under 2 MB assert os.path.getsize(zip_filename) / 1024**2 < 2 print(zip_count(zip_filename))

Una vez que lo haya exportado a los archivos .py desnudos, su código probablemente aún no estará estructurado en clases. Pero vale la pena el esfuerzo de haber refabricado su computadora portátil hasta el punto en que tiene un conjunto de funciones documentadas, cada una con un conjunto de afirmaciones simples que pueden trasladarse fácilmente a tests.py para probar con pytest , unittest o lo que tenga tú. Si tiene sentido, agrupar estas funciones en métodos para sus clases está muerto, es fácil después de eso.

Si todo va bien, todo lo que debe hacer después de eso es escribir su nombre if __name__ == ''__main__'': y sus "ganchos": si está escribiendo un script para que lo llame el terminal, querrá manejar el comando argumentos de línea , si está escribiendo un módulo, querrá pensar en su API con el archivo __init__.py , etc.

Todo depende de cuál sea el caso de uso previsto, por supuesto: existe una gran diferencia entre convertir un cuaderno en un pequeño guión o convertirlo en un módulo o paquete completo.

Aquí hay algunas ideas para un flujo de trabajo de cuaderno a script :

  1. Exporte el archivo Jupyter Notebook a Python (.py) a través de la GUI.
  2. Elimine las líneas de "ayuda" que no hacen el trabajo real: print declaraciones, tramas, etc.
  3. Si es necesario, agrupa tu lógica en clases. El único trabajo adicional de refactorización requerido debe ser escribir los documentos y atributos de su clase.
  4. Escriba las entradas de su script con if __name__ == ''__main__'' .
  5. Separe sus declaraciones de afirmación para cada una de sus funciones / métodos, y desarrolle un conjunto mínimo de pruebas en tests.py .

El portátil Jupyter (iPython) se conoce merecidamente como una buena herramienta para crear prototipos del código y hacer todo tipo de cosas de aprendizaje automático de forma interactiva. Pero cuando lo uso, inevitablemente encuentro lo siguiente:

  • el portátil se vuelve demasiado complejo y desordenado para ser mantenido y mejorado aún más como un bloc de notas, y tengo que hacer scripts de Python;
  • cuando se trata del código de producción (por ejemplo, uno que debe volver a ejecutarse todos los días), el portátil no es el mejor formato.

Supongamos que he desarrollado una línea completa de aprendizaje automático en jupyter que incluye la obtención de datos en bruto de diversas fuentes, limpieza de datos, ingeniería de características y modelos de capacitación, después de todo. ¿Cuál es la mejor lógica para crear scripts con un código eficiente y legible? Solía ​​abordarlo de varias maneras hasta ahora:

  1. Simplemente convierta .ipynb a .py y, con solo ligeros cambios, codifique todo el pipeline del cuaderno en un script de python.

    • ''+'': rápido
    • ''-'': sucio, no flexible, no conveniente de mantener
  2. Cree una secuencia de comandos única con muchas funciones (aproximadamente, 1 función para cada celda), intente comprender las etapas de la interconexión con funciones separadas y asígneles el nombre correspondiente. Luego especifique todos los parámetros y constantes globales a través de argparse .

    • ''+'': uso más flexible; código más legible (si ha transformado correctamente la lógica de la tubería a funciones)
    • ''-'': muchas veces, la canalización NO se puede dividir en partes lógicamente completas que podrían convertirse en funciones sin ninguna peculiaridad en el código. Todas estas funciones son típicamente necesarias para ser llamadas una sola vez en el script en lugar de ser llamadas muchas veces dentro de loops, mapas, etc. Además, cada función generalmente toma el resultado de todas las funciones llamadas anteriormente, por lo que uno tiene que pasar muchos argumentos a cada uno función.
  3. Lo mismo que el punto (2), pero ahora ajusta todas las funciones dentro de la clase. Ahora todas las constantes globales, así como las salidas de cada método se pueden almacenar como atributos de clase.

    • ''+'': no ​​necesita pasar muchos argumentos a cada método, todos los productos anteriores ya están almacenados como atributos
    • ''-'': la lógica general de una tarea aún no se captura, es un canal de datos y de aprendizaje automático, no solo de clase. El único objetivo para la clase es crearlo, llamar a todos los métodos de forma secuencial uno por uno y luego eliminarlos. Además de esto, las clases son bastante largas de implementar.
  4. Convertir un cuaderno en el módulo de Python con varios scripts. No probé esto, pero sospecho que esta es la forma más larga de lidiar con el problema.

Supongo que este escenario general es muy común entre los científicos de datos, pero sorprendentemente no puedo encontrar ningún consejo útil.

Amigos, por favor, compartan sus ideas y experiencias. ¿Alguna vez te has encontrado con este problema? ¿Cómo lo has abordado?


Estamos teniendo el problema similar. Sin embargo, estamos usando varios portátiles para crear prototipos de los resultados que, después de todo, también deberían convertirse en varios scripts de Python.

Nuestro enfoque es que dejamos de lado el código, que parece repetirse en esos cuadernos. Lo colocamos en el módulo python, que es importado por cada computadora portátil y también se utiliza en la producción. Mejoramos iterativamente este módulo continuamente y agregamos pruebas de lo que encontramos durante la creación de prototipos.

Los portátiles se vuelven más bien como los scripts de configuración (que simplemente copiamos en los archivos de python resultantes finales) y varias comprobaciones y validaciones de prototipos, que no necesitamos en la producción.

Sobre todo no tenemos miedo de la refactorización :)