Publicación pública de Muttlib
Aumente la velocidad de desarrollo de su proyecto de datos

¿Qué es muttlib?
A lo largo de muchos proyectos de datos, notamos necesidades compartidas. Las necesidades compartidas conducen a las compartidas (que es un eufemismo para copiar y pegar), y el paso natural es centralizar todo ese código en una única base de código donde pueda agregar pruebas, aplicar las mejores prácticas y distribuirlo fácilmente. muttlib se propuso ser exactamente eso: una biblioteca de ayudantes y utilidades que, aunque no sea fundamental para ningún proyecto, la mayoría de los proyectos de Mutt tendrían como núcleo.
Ya conoces el procedimiento: tienes algún problema, escribes un pequeño y bonito módulo de utilidades que resuelve precisamente eso. Pasan unos meses y, en una semana, alguien dice que va a resolver exactamente lo mismo que tú ya resolviste en otro proyecto. Entonces, se lo dices y... ¿qué podrían hacer, aparte de copiarlo y pegarlo descaradamente en su propia base de código? Tal vez incluso la suite de pruebas (si hubiera alguna y les pareciera sofisticada). Esto era algo común, por lo que, cualquier pequeñas y bonitas utilidades ahora entra en muttlib.
Como muttlib centraliza todo este código, es más fácil de mantener: las pruebas se pueden agregar o actualizar según sea necesario, las correcciones y mejoras se encuentran en un solo lugar, así como cualquier regresión que deba corregirse. La mayoría de las personas que trabajan en Mutt, si no todas, tienen acceso de escritura al repositorio, por lo que las correcciones suelen hacerse rápidamente. Esto siempre y cuando se aprueben todas las comprobaciones de CI y se haya seguido todo lo que aparece en el Pauta de contribución escribimos desde el principio cuando nos propusimos lanzarlo públicamente.
Los inicios y el camino hacia este lanzamiento público
La primera confirmación de Muttlib se remonta al 26 de enero de 2019. Por esa época, albergaba funciones que se habían escrito para diferentes proyectos pero que no eran específicas para ninguno de ellos, por lo que podían reutilizarse (o ya habían sido) reutilizadas en varios proyectos.
Desde entonces, ha seguido creciendo sin parar hasta convertirse en un depósito general de funciones inespecíficas. Lo cual, en ese momento, era bastante útil. Sin embargo, se había salido de control y se había vuelto un poco desordenada.
Cuando establecimos el hito de hacer un lanzamiento público antes del final del cuarto trimestre de 2020, tuvimos que evaluar, priorizar y clasificar todos los temas que ya habíamos abierto. Pero también otros nuevos que definían qué y cómo queríamos que fuera muttlib's 1.0: una guía de referencia para otros proyectos de Mutt Data sobre cómo creemos que deben estructurarse los proyectos y cómo y qué herramientas deben usarse para hacer cumplir las mejores prácticas.
Esto incluía todo, desde confirmación previa y configuración Esfinge para la documentación, hasta trabajos de CI que comprueben que el se ha modificado el número de versión y se modificó el registro de cambios.
Queríamos que todos en Mutt Data participaran, por lo que, por lo general, los nuevos empleados tenían algunos problemas como parte de su incorporación inicial.
¿Qué tipo de utilidades encontrarás en Muttlib?
dbconn
Este módulo proporciona conectores a varias bases de datos comunes. Es compatible con la mayoría de las versiones populares de RDBMS, como sqlite, postgres, mysql, servidor sql, oráculo, teradata así como NoSQL como mongo.
Si necesitas pasar al modo BIG DATA dbconn también tiene una interfaz para ibis para Apache Impala (un sistema MPP sobre Hadoop), el de Google gran consulta, Apache colmena y esto es solo el principio.
¿Falta tu base de datos favorita? No hay problema, puedes enviar un problema solicitando que se añada como nueva función. ¿Ya tienes algún código o idea? Mejor aún, podrías proponerlo como solicitud de fusión. Nos encanta la colaboración, solo tienes que seguir nuestro pautas para empezar.
¿Qué puedes hacer con él?
Imagínese el siguiente escenario. Últimamente, tu negocio se está disparando:. Empiezas a adquirir nuevos clientes de todo el mundo y tienes algunas preguntas. Decides obtener algunos de los datos de ubicación de tus clientes enmarcar de tu producto base de datos que usa oraciones SQL simples para luego hacer un análisis mágico ad hoc con pandas. Esto se puede lograr rápidamente con un fragmento corto, como el siguiente:
fromMuttlibImportDBConnClients_DB=dbconn.pgClient (username="ninja_business_analyst», database="clients», host="my.database.product.io», port="5432", password="5tr0ngp45Sword»,) query=" "» SELECCIONE client_id, país, ciudad DE CLIENTS_location DONDE main_country_language = 'ESPAÑOL' «" "customers_df=clients_db.to_frame (query) customers_df.head (10) # client_id country city# 0 296377 ARGENTINA CABA# 1 296382 ARGENTINA CABA# 2 296145 VENEZUELA BARQUISIMETO# 3 296224 VENEZUELA CARACAS# 4 296230 ARGENTINA None# 5 296448 ESPAÑA BARCELONA# 6 296450 ESPAÑA MARBELLA# 7 296447 ARGENTINA CÓRDOBA# 8 296449 ARGENTINA MENDOZA# 9 296451 ARGENTINA ENTRE RIOS# su análisis acaba de empezar...
Después de hacer algunas transformaciones ninja, es posible que desees: insertar_desde_marco a tu negocio base de datos, para luego crear algunas visualizaciones con una integración de herramientas de BI. Podrías hacer:
# código ninja arriba... business_db=dbconn.mysqlClient (username="ninja_business_analyst», database="clients», host="my.database.business.io», port="3306", password="5tr0ngp45sword»,) business_db.insert_from_frame (df=customers_df, table="clients_location»)
Después de mostrar su dataviz para sus socios, logró encontrar los valores correctos que faltaban, por lo que puede actualizar la base de datos de su empresa con una simple oración SQL y actualizarla de inmediato:
# más código ninja arriba... query=" "» UPDATE clients_location SET city = 'CABA' DONDE country = 'ARGENTINA' Y LA CIUDAD ES NULA «" "business_db.execute (query)
Lo sé, era un escenario simple, pero entiendes el punto, ¿verdad?
tramando
Proporciona un módulo auxiliar para ayudarlo a construir parcelas aprovechando el uso matplotlib. Probemos con un ejemplo:
Imagina que, después de ajustar tu modelo de previsión, quieres crear algunas visualizaciones de su rendimiento mejorado para mostrarlas en la sincronización semanal de tu equipo. En este punto, tienes historia_de_ventas y previso_de_ventas marcos de datos:
#... algún código de aprendizaje automático por encima de sales_history.tail () # ds y# 23 2020-12-01 501232# 24 2021-01-01 397252# 25 2021-02-01 386935# 26 2021-03-01 444110# 27 2021-04-01 438217sales_forecast.head () # ds yhat# 28 2021-05-01 462615# 29 2021-06-01 448229# 30 2021-06-01 448229# 30 2021-05-01 7-01 457710# 31 2021-08-01 456340# 32 2021-09-01 430917
Podrías create_forecast_figure fácilmente con unas pocas líneas:
frommuttlib.plotingimportplot, constantsasconstsales_forecast=sales_forecast.rename (columns= {const.y_col:const.yhat_col}) sales_forecast.head () full_series=pd.concat ([sales_forecast, sales_history]) full_series [const.ds_col] =pd.to_datetime (full_series [const.ds_col]) full_series.head () end_date=pd.to_datetime (sales_forecast [const.ds_col]) .min () forecast_window= (pd.to_datetime (sales_forecast [const.ds_col]) .max () -end_date) .daysfig=plot.create_forecast_figure (full_date) series, "test», end_date, forecast_window, time_granularity=const.daily_time_granularity, plot_config=deepcopy (const. PLOT_CONFIG), fig.show ()

procesamiento de archivos
Este módulo proporciona funciones y clases convenientes para cambiar el nombre de los archivos después de operaciones exitosas y el procesamiento en paralelo de nuevos archivos. Imagina esta situación:
Anoche, dejaste algunos datos históricos de ventas de la descarga de tu aplicación principal. El objetivo es realizar algunos análisis como exploración preliminar de su proyecto de aprendizaje automático. En la actualidad, querrás inspeccionar y preparar esos archivos antes de que comience la magia. Puede iniciar esa tarea usando obtener archivos nuevos de esta manera:
de muttlibimportfile_processingdownloaded_file_path=f'/tmp/sales_data'file_processing.get_new_files (downloaded_file_path) # ['/tmp/sales_data/2021/04/sales.data', # '/tmp/sales_data/2021/03/sales.data', # '/tmp/sales_data/2021/02/sales.data', # '/tmp/sales_data/2021/02/sales.data' es.data ', #' /tmp/sales_data/2021/01/sales.data ', #' /tmp/sales_data/2020/12/sales.data ', #' /tmp/sales_data/2020/11/sales.data ', #' /tmp/sales_data/2020/10/sales.data ', #' /tmp/sales_data/2020/09/sales.data ', #' /tmp/sales_data/2020/08/sales.data ', #' /tmp/sales_data/2020/07/sales.data '] #... más código de exploración
Observa, en sus archivos, que los datos están separados por tuberías -- y esto no te gusta -, porque eres fanático de los archivos separados por punto y coma. Podrías solucionar este problema fácilmente con procesar_archivos_nuevos y una función de transformación sencilla. Este enfoque tendría un aspecto similar al siguiente:
#... más código de exploración defreplace_column_separator (filename, rbr) :withinput_file as open (filename, «rt») :data=input_file.read () .replace ('|', ';') sin put_file as open (filename, «wt») output_file.write (data) return trueExcept:returnFile_Processing.process_process__archivos (reemplazar separador de columnas, '/tmp/sales_data')
pronóstico
Este módulo ofrece Profeta FB una interfaz similar a Sklearn y resuelve las utilidades generales para problemas de previsión. Por ejemplo, limitar los conjuntos de datos al último n días, lo que permite espacios de búsqueda de hiperparámetros en cuadrículas más grandes y no está disponible con el estándar Profeta FB y Sklearn bibliotecas.
Profeta SKuna interfaz compatible con Scikit learn para fbProphet yEstimador selector de pasoscomo selector de estimadores.
Ambos tienen una interfaz común: - ajuste y predecir Scikit aprende métodos similares al modelo del Profeta y, - get_params y set_params métodos para obtener y establecer los parámetros del estimador, respectivamente.
Vamos a echar un vistazo a cómo pronóstico podría usarse con el siguiente fragmento:
ImportPandasAS.PDFromMuttlib.ForecasImport.SKProphet, StepsSelectorEstimatorFromSklearn.model_selectionImportGridSearchCV, ParameterGrid# La cuadrícula debe convertirse en una lista si se usa en un StepsSelectorEstimator#, ya que debe poder copiarse para get/set paramsprophet_grid=list (ParameterGrid ({"sk__date_column»: ["date"], "sk_yhat_only»: [Verdadero], "sk_extra_regressors»: [[], [{"name» :"b "}], "prophet_kwargs»: [dict (daily_seasonality="auto»), dict (daily_seasonality=true),],}) days_selector_grim d= {"estimator_class»: [SKProphet], "amount_of_steps»: [90.120], "sort_col»: ["fecha"], "estimator_ kwargs» :prophet_grid,} # Para crear una instancia de GridSearchCV, necesitamos pasar un estimador inicializado# (por ejemplo, un `StepsSelectorEstimator`) INITIAL_ESTIMATOR=StepsSelectoresEstimator (SKProphet, days_selector_grid ["amount_of_steps"] [0], prophet_grid [0]) CV=gridGridsearchCV (initial_estimator, days_selector_grid, cv=2, scoring="r2") x=pd.DataFrame ({"date»: [0,2,3,4,5], "b»: [1,4,5,0,9]}) y=pd.series ([1,1,0,1,0]) cv.fit (X, y)
gdrive
Este módulo proporciona una interfaz similar a la de Unix para Google Drive para ayudarte a integrarla en tus canalizaciones. La mayoría de nosotros, si no todos, estamos lo suficientemente familiarizados con el terminal como para entender cómo funciona este módulo. En lugar de familiarizarte con un cliente de GDrive, puedes usar GDrive de la misma manera que usas tu propio sistema de archivos.
Si su cliente necesita obtener informes en una carpeta compartida, ¡puede crearla, compartirla y completarla fácilmente con este módulo! O si estás trabajando en un cuaderno de Jupyter y necesitas averiguar rápidamente en qué parte de GDrive tendrías que guardar el resultado de tus análisis, también puedes usarlo.
Desde muttlib.gdriveimportgdrivegoogle_service_account_creds_json=» /some/local/dir/path/to/json/file.json"gdrive_client=gdrive (GOOGLE_SERVICE_ACCOUNT_CREDS_JSON)
Más acerca de cómo crear y administrar las claves de las cuentas de servicio de Google
Puede enumerar todos los archivos de la carpeta actual usando eso bien conocidols orden
#... gdrive_client.ls ()
¿No estás seguro de cuál es la carpeta actual? Imprímela con pawd
#... gdrive_client.pwd ()
¿Vas a mudarte a otra carpeta? Sí, puedes usar cd
#... # Nombre del nuevo DirectoryFolder_Name='data'gDrive_Client.cd (folder_name)
Ahora que estás familiarizado y quieres empezar creando. mkdir será útil si necesita un nuevo directorio
#... # Nombre de la nueva carpeta para crear NEW_FOLDER_NAME='Reports'GDRIVE_CLIENT.mkdir (new_folder_name)
Y luego crear un nuevo archivo de un archivo específico tipo MIME en esta carpeta con toque
#... # Nombre del nuevo archivo para createNew_file_name='sales'# un mimetypemime_type='application/vnd.google-apps.spreadsheet'gdrive_client.touch (new_file_name, mime_type)
Más acerca de Tipos MIME.
Por último, pero no por ello menos importante, ahogado conceder o transferir permisos para una carpeta o un archivo del directorio actual
#... # Correo electrónico del cesionario.email=' user@mycompany.ai '# Función del cesionario: # propietario, organización, organizador de archivos, escritor, comentarista o readerrole='commenter'# Tipo de permiso a conceder: # usuario, grupo, dominio o anyonepermission_type='user'gdrive_client.chown (email, role, permission_type)
Más acerca de Permisos.
gsheetsconn
Pero... cómo volcar un marco de datos en el GSheet que acabas de crear con el gdrive módulo? Bueno, el gsheetsconn el módulo está aquí para ayudarte, proporcionando una interfaz de pandas con Google Sheets.
Frommuttlib.gsheetsconnImportgSheetsClientgoogle_service_account_creds_json=» /some/local/dir/path/to/json/file.json» gsheets_client=GSheetsClient (google_service_account_creds_json)
Uso insertar_desde_marco le ayudará a hacer el trabajo
#... gsheets_spread_id="some-google-sheets-id"gsheets_worksheet_name="contactos de correo electrónico de los clientes"gsheets_client.insert_from_frame (customer_email_contacts_df, gsheets_spread_id, index=true, worksheet=gsheets_worksheet_name,)
Ahora que eres imparable, trabajar con otra hoja de cálculo en pandas será más fácil, solo necesitas usar enmarcar
#... gsheets_spread_id="some-google-sheets-id"gsheets_worksheet_name="gsheets-worksheet-name"return_df=gsheets_client.to_frame (GSHEETS_SPREAD_ID, hoja de trabajo=GSHEETS_WORKSHEET_NAME)
utilidades
Este módulo proporciona un conjunto de funciones utilitarias independientes del proyecto para ayudarlo a abordar algunas de esas tareas monótonas y no tan triviales pero necesarias cuando trabaja en un proyecto. Exploremos algunas de ellas con un escenario común:
Tu cliente finalmente te envió un conjunto de datos con más información sobre sus clientes, algo que estabas esperando para continuar con tu proyecto de aprendizaje automático.
importpandasdf=pandas.read_csv ('customers_more_info.csv') df.head () # CustomerName CustomerAge Artículos comprados# 0 Juan 25 15# 1 Pedro 43 #2 Mateo 62 #1 3 Pablo 19 5# 4 Jesús 33 66
Lo primero que observas es que los nombres de las columnas de este nuevo conjunto de datos utilizan mayúsculas y minúsculas diferentes a las del resto de los marcos con los que estás trabajando. La primera tarea de tu lista de tareas pendientes, en aras de la coherencia del proyecto, consiste en convertir todos los nombres de las columnas utilizando convertir a snake_case
importpandasfrommuttlibiimportutilsdf=pandas.read_csv (» customers_more_info.csv «) df.columns= [utils.convert_to_snake_case (column) forcolumnindf.columns] df.head () # customer_name customer_age items_purchased# 0 Juan 25 15# 1 Pedro 43 2# 2 Mateo 62 1# 3 Pablo 19 5# 4 Jesús 33 66
Después de un tiempo, tiene una primera versión de su modelo de aprendizaje automático y desea ejecutar algunos experimentos con diferentes generado aleatoriamente subconjuntos para evaluarlo. También quieres tener el control de tu semilla aleatoria y capacidades de reproducibilidad para obtener y compartir información valiosa sobre su prueba. Puede archivarlo usando numpy_temp_seed de esta manera:
frommuttlibimportutils# Código de aprendizaje automático... defrun_some_experiment (df, n) :df=df.sample (n) # Código de experimento... returndfwithutils.numpy_temp_seed (42) :test_df=run_some_experiment (df,5) test_df.head () # customer_name result# 0 Juan 0.123# 1 Pedro 0.456# 2 Matt Eo 0.789# 3 Pablo 0.012# 4 Jesús 0.666
Documentos de Sphinx
Uno de los primeros objetivos que nos propusimos para hacer que la biblioteca fuera más fácil de usar fue crear documentación con capacidad de búsqueda y de fácil acceso. Nos conformamos con esfinge como nuestra herramienta preferida. Ahora la gente no necesitaría profundizar en el código para ver qué capacidades tenía para ofrecer. Tras un rápido trabajo de configuración e interfaz de usuario, ya estaba listo. Por supuesto, se hicieron algunos ajustes, pero por lo general es bastante sencillo añadir documentos de Sphinx a tu proyecto.
Puede encontrar los documentos ordenados y con capacidad de búsqueda en https://mutt_data.gitlab.io/muttlib/.
CI/CD y todo lo que hace que muttlib sea tan genial
A lo largo de nuestro recorrido, muttlib se convirtió en una referencia para varios de nuestros otros proyectos mediante la creación de un conjunto de herramientas que (creemos) hace que el desarrollo sea más fácil y menos propenso a errores.
Para empezar, ya que era un colaborativo proyecto, redactamos (y volvimos a redactar y mejoramos) un CONTRIBUYENTE.md archivo, destinado a explicar cómo ayudar a construir muttlib. Esto es crucial para que los nuevos empleados y colaboradores comiencen a hacer contribuciones significativas.
Este documento incluye notas sobre la configuración del proyecto, cómo usarlo confirmación previa, la guía de estilo que utilizamos, cómo escribir cadenas de documentación adecuadas, cómo ejecutar pruebas, el control de versiones, la obsolescencia, el lanzamiento y el flujo de trabajo de GitLab. Es una lectura pesada, pero vale la pena a largo plazo, ya que todo el mundo sabe cómo funciona cada paso del ciclo de lanzamiento.
Desde el primer día nos centramos en automatizar todas las tareas menores: - Ejecutar pruebas - Asegurarnos de que el código tenía el estilo correcto usando negro - Compruebe si el código tiene cadenas de documentación - Asegúrese de que no se hayan introducido vulnerabilidades de seguridad mediante Bandido - Implemente la documentación actualizada de sphinx - Implemente la nueva versión en el registro de PyPI o gitlab - Si se trataba de una versión sin etiquetas, solo para probar los registros - ¡Asegúrese de que la versión no esté etiquetada! - Asegúrese de que el registro de cambios se haya actualizado
Todas estas comprobaciones se ejecutan en GitLab CI. Lo bueno de esto es que podemos reutilizar sin problemas estos trabajos probados en otros proyectos.
confirmación previa merece un poco más de atención aquí. Esta herramienta para ejecutar ganchos en las diferentes etapas del flujo de trabajo de git es la base de la calidad del código para nosotros hoy en día. Claro, algunos de nosotros usamos complementos de vim o vscode que ejecutan linters, formateadores y demás. Pero confirmación previa tiene la última palabra.
Al momento de escribir esto, estamos corriendo negro, mypy, pylint al confirmar. Al empujar, corremos (a través de nox) pruebas, linteros y bandido. Por lo tanto, se supone que todo el código que insertamos debe pasar todas las pruebas y tener el formato correcto, pero lo aplicamos en un entorno nuevo en CI.
Hay muchas herramientas involucradas. Sin embargo, las adoptamos por varias razones. En primer lugar, son útiles para su propósito. En segundo lugar, disponer de un flujo de trabajo estandarizado deja poco margen para que surjan opiniones contradictorias sobre varios aspectos del mismo. En tercer lugar, se pueden automatizar. Y cuando sepas cómo trabajar en un proyecto, puedes echar una mano en otro si es necesario y también sabrás cómo funciona.
Duplicación de GitHub
Principalmente utilizamos Gitlab (hay una disputa constante entre GitHub y Gitlab en nuestro Slack), pero mucha gente prefiere usar GitHub y allí descubren y escriben código con estrellas. Mutt Data está en GitHub, aunque sin mucha actividad. Sin embargo, para que sea más fácil para todos, hemos copiado muttlib de Gitlab a GitHub.
Problemas en github
El punto principal de hacer esto es que si no tienes una cuenta de Gitlab, puedes abrir problemas en GitHub.
No tenemos ningún problema pendiente allí, pero estamos prestando atención.
¿Qué sigue?
El 2021 no está exento de desafíos. Esperamos mejorar la API, la documentación y las pruebas, así como la coherencia de nuestros módulos. Sin mencionar que creemos dbconn aún le queda algo por madurar.
Una gran parte de nuestro objetivo de publicar Muttlib consistió en revisar todo lo que había llegado a la biblioteca en los últimos años. Este proceso nos hizo conscientes de lo que teníamos previsto para Muttlib y reveló un código que realmente no cabía en la biblioteca o que apenas era útil. Puede que hayas adivinado que es el destino: el mejor código es no tener código.
Una vez hecho esto, nos resultó más fácil avanzar en la dirección que ahora imaginábamos con mayor claridad: Muttlib es una biblioteca de ayudantes que facilita los proyectos de datos para los fanáticos de los datos.
Finalizando
Muttlib es el resultado del esfuerzo conjunto de los siguientes talentosos fanáticos de los datos: - Aldo Escobar - Alejandro Rusi - Cristián Antuña - Eric Rishmuller - Fabian Wolfmann - Gabriel Miretti - Javier Mermet - Jose Castagnino - Juan Pampliega - Luis Alberto Hernandez - Mateo de Monasterio - Matías Battocchia - Pablo Lorenzatto - Pedro Ferrari - Santiago Hernandez
Ha sido (y espero que siga siendo) una gran experiencia construir Muttlib juntos como equipo. Gracias a todos ellos.
Latest Insights
¿Cómo sabes que es hora de hacer evolucionar tu marca?
.webp)
El lenguaje natural se une a los datos en tiempo real: análisis sin cuellos de botella

No todos los optimizadores de medios online están diseñados de la misma manera
