├── leila ├── __init__.py ├── datos_gov.py ├── reporte.py └── templates │ └── template.html ├── MANIFEST.in ├── recursos ├── LEILA.jpg ├── leila.png ├── create_fork.png ├── vista_reporte.gif ├── vista_reporte.jpg ├── issues_contexto.PNG ├── barra_pull_request.png ├── comparing_changes.png ├── Welcome_pull_requests.png ├── documentacion_ejemplo.PNG ├── formulario_pull_request.png └── boton_create_pull_request.png ├── sphinx ├── source │ ├── _static │ │ ├── image │ │ │ ├── LEILA.jpg │ │ │ ├── leila.png │ │ │ ├── favicon.ico │ │ │ ├── logo_400.png │ │ │ └── vista_reporte.jpg │ │ └── css │ │ │ └── custom.css │ ├── ejemplos │ │ ├── header_ejemplos.rst │ │ ├── header_ejemplos_3.rst │ │ ├── header_ejemplos_2.rst │ │ ├── ejemplos_reporte.rst │ │ ├── ejemplos_calidad_datos.rst │ │ └── ejemplos_datos_gov.rst │ ├── funciones │ │ ├── datos_gov.rst │ │ ├── calidad_datos.rst │ │ └── reporte.rst │ ├── instalacion.rst │ ├── index.rst │ ├── introduccion.rst │ ├── conf.py │ └── control_de_cambios.rst ├── Makefile └── make.bat ├── .gitignore ├── LICENSE ├── setup.py ├── README.md └── CHANGELOG.md /leila/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include leila/templates/template.html -------------------------------------------------------------------------------- /recursos/LEILA.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/LEILA.jpg -------------------------------------------------------------------------------- /recursos/leila.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/leila.png -------------------------------------------------------------------------------- /recursos/create_fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/create_fork.png -------------------------------------------------------------------------------- /recursos/vista_reporte.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/vista_reporte.gif -------------------------------------------------------------------------------- /recursos/vista_reporte.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/vista_reporte.jpg -------------------------------------------------------------------------------- /recursos/issues_contexto.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/issues_contexto.PNG -------------------------------------------------------------------------------- /recursos/barra_pull_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/barra_pull_request.png -------------------------------------------------------------------------------- /recursos/comparing_changes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/comparing_changes.png -------------------------------------------------------------------------------- /recursos/Welcome_pull_requests.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/Welcome_pull_requests.png -------------------------------------------------------------------------------- /recursos/documentacion_ejemplo.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/documentacion_ejemplo.PNG -------------------------------------------------------------------------------- /recursos/formulario_pull_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/formulario_pull_request.png -------------------------------------------------------------------------------- /sphinx/source/_static/image/LEILA.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/sphinx/source/_static/image/LEILA.jpg -------------------------------------------------------------------------------- /sphinx/source/_static/image/leila.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/sphinx/source/_static/image/leila.png -------------------------------------------------------------------------------- /recursos/boton_create_pull_request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/recursos/boton_create_pull_request.png -------------------------------------------------------------------------------- /sphinx/source/_static/image/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/sphinx/source/_static/image/favicon.ico -------------------------------------------------------------------------------- /sphinx/source/_static/image/logo_400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/sphinx/source/_static/image/logo_400.png -------------------------------------------------------------------------------- /sphinx/source/_static/image/vista_reporte.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ucd-dnp/leila/HEAD/sphinx/source/_static/image/vista_reporte.jpg -------------------------------------------------------------------------------- /sphinx/source/ejemplos/header_ejemplos.rst: -------------------------------------------------------------------------------- 1 | .. |Ejemplos| raw:: html 2 | 3 |

Ejemplos

4 | 5 | .. |hr| raw:: html 6 | 7 |
8 | 9 | 10 | |Ejemplos| 11 | |hr| -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ignore compilation files 2 | dist 3 | crear_whl.bat 4 | 5 | # ignore Excel files 6 | *.xlsx 7 | *.tsv 8 | 9 | # ignore virtual env 10 | env 11 | 12 | # ignore other files 13 | .idea 14 | __pycache__ 15 | 16 | sphinx/build 17 | data/ 18 | prueba.py 19 | .vscode -------------------------------------------------------------------------------- /sphinx/source/funciones/datos_gov.rst: -------------------------------------------------------------------------------- 1 | .. _datos_gov: 2 | 3 | Datos gov 4 | ========= 5 | 6 | Este módulo permite conectar y evaluar desde el código los metadatos del Portal de Datos Abiertos y descargar las bases de datos a dataframes. 7 | 8 | .. automodule:: datos_gov 9 | :members: 10 | :undoc-members: 11 | :show-inheritance: 12 | :exclude-members: asset_inventory_espanol 13 | 14 | .. include:: ../ejemplos/header_ejemplos.rst 15 | .. include:: ../ejemplos/ejemplos_datos_gov.rst 16 | :start-line: 3 -------------------------------------------------------------------------------- /sphinx/source/funciones/calidad_datos.rst: -------------------------------------------------------------------------------- 1 | .. _calidad_datos: 2 | 3 | Calidad datos 4 | ============= 5 | 6 | Este módulo se enfoca en analizar cualquier base de datos (dataframe) de interés para el usuario. Se tiene acceso a funciones de estadísticas descriptivas, cálculo de memoria, registros duplicados, faltantes y otras. 7 | 8 | .. automodule:: calidad_datos 9 | :members: 10 | :undoc-members: 11 | :show-inheritance: 12 | :exclude-members: correlacion_cramerv 13 | 14 | 15 | .. include:: ../ejemplos/header_ejemplos_3.rst 16 | .. include:: ../ejemplos/ejemplos_calidad_datos.rst 17 | :start-line: 3 -------------------------------------------------------------------------------- /sphinx/source/instalacion.rst: -------------------------------------------------------------------------------- 1 | .. _instalacion: 2 | 3 | Instalación 4 | =========== 5 | 6 | Para la instalación de la librería se debe utilizar el gestor de paquetes ``pip``, por buenas prácticas se sugiere antes de la instalación crear un entorno virtual que permita aislar las librerías y evitar conflictos de versiones con el entorno de desarrollo base del computador. 7 | 8 | .. code-block:: console 9 | 10 | pip install leila 11 | 12 | De manera alterna también puede utilizar el gestor de paquetes ``conda``. 13 | 14 | .. code-block:: console 15 | 16 | conda install -c ucd-dnp -c conda-forge leila 17 | -------------------------------------------------------------------------------- /sphinx/source/index.rst: -------------------------------------------------------------------------------- 1 | LEILA - Librería de calidad de datos 2 | ==================================== 3 | 4 | .. toctree:: 5 | :maxdepth: 2 6 | :caption: LEILA: 7 | :hidden: 8 | 9 | introduccion 10 | instalacion 11 | 12 | .. toctree:: 13 | :maxdepth: 2 14 | :caption: Módulos y funciones: 15 | :hidden: 16 | 17 | funciones/calidad_datos 18 | funciones/datos_gov 19 | funciones/reporte 20 | 21 | .. toctree:: 22 | :maxdepth: 2 23 | :caption: Otros: 24 | :hidden: 25 | 26 | control_de_cambios 27 | 28 | .. figure:: _static/image/leila.png 29 | :align: center 30 | :alt: 31 | :figclass: align-center 32 | 33 | 34 | .. include:: introduccion.rst 35 | :start-line: 4 -------------------------------------------------------------------------------- /sphinx/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line, and also 5 | # from the environment for the first two. 6 | SPHINXOPTS ?= 7 | SPHINXBUILD ?= sphinx-build 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /sphinx/source/ejemplos/header_ejemplos_3.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../ejemplos/header_ejemplos.rst 2 | 3 | A continuación se presentan ejemplos de uso, el código y resultado esperado de estos. Los datos utilizados para los ejemplos corresponden a una muestra de los **Casos positivos de COVID-19 en Colombia** disponibles en el portal de `Datos Abiertos de Colombia`_, se debe aclarar que los datos fueron modificados con el propósito de presentar el alcance de las diferentes funciones de la librería. 4 | 5 | .. _Datos Abiertos de Colombia: https://www.datos.gov.co/Salud-y-Protecci-n-Social/Casos-positivos-de-COVID-19-en-Colombia/gt2j-8ykr 6 | 7 | En caso que desee utilizar los datos utilizados en los ejemplos, puede descargarlos utilizando el siguiente link. :download:`Descargar datos (6.2 MB)`. 8 | 9 | |hr| -------------------------------------------------------------------------------- /sphinx/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | 13 | if "%1" == "" goto help 14 | 15 | %SPHINXBUILD% >NUL 2>NUL 16 | if errorlevel 9009 ( 17 | echo. 18 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 19 | echo.installed, then set the SPHINXBUILD environment variable to point 20 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 21 | echo.may add the Sphinx directory to PATH. 22 | echo. 23 | echo.If you don't have Sphinx installed, grab it from 24 | echo.http://sphinx-doc.org/ 25 | exit /b 1 26 | ) 27 | 28 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 29 | goto end 30 | 31 | :help 32 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% 33 | 34 | :end 35 | popd 36 | -------------------------------------------------------------------------------- /sphinx/source/_static/css/custom.css: -------------------------------------------------------------------------------- 1 | p { 2 | text-align: justify; 3 | } 4 | 5 | li { 6 | text-align: justify; 7 | } 8 | 9 | p[class="caption"] { 10 | text-align: center; 11 | } 12 | 13 | div[class="wy-menu wy-menu-vertical"] p[class="caption"] { 14 | text-align: left; 15 | } 16 | 17 | .wy-nav-content { 18 | max-width: 1200px !important; 19 | } 20 | 21 | /* replace the copyright to eliminate the copyright symbol enforced by 22 | the ReadTheDocs theme but eschewed by our legal team */ 23 | div[role=contentinfo] { 24 | visibility: hidden; 25 | position: relative; 26 | } 27 | 28 | div[role=contentinfo]:after { 29 | visibility: visible; 30 | position: absolute; 31 | top: 0; 32 | left: 0; 33 | <<<<<<< HEAD:sphinx/source/_static/css/custom.css 34 | content: "Departamento Nacional de Planeación - 2021"; 35 | ======= 36 | content: "Departamento Nacional de Planeación - 2020"; 37 | >>>>>>> master:docs/_static/css/custom.css 38 | } -------------------------------------------------------------------------------- /sphinx/source/funciones/reporte.rst: -------------------------------------------------------------------------------- 1 | .. _reporte: 2 | 3 | .. |ul| raw:: html 4 | 5 | 10 | 11 | .. |li| raw:: html 12 | 13 |
  • 14 | 15 | .. |/li| raw:: html 16 | 17 |
  • 18 | 19 | .. |br| raw:: html 20 | 21 |
    22 | 23 | Reporte 24 | ======= 25 | 26 | La función ``generar_reporte(base)`` busca facilitar el proceso de entendimiento de la calidad de datos de una base de datos de interés, para esto genera un reporte en formato HTML el cual consolida las funciones de calidad de datos implementadas en el módulo :ref:`leila.calidad_datos ` y :ref:`leila.datos_gov `, facilitando la consulta de los resultados obtenidos del análisis exploratorio en un archivo independiente. 27 | 28 | .. automodule:: reporte 29 | :members: 30 | :undoc-members: 31 | :show-inheritance: 32 | :exclude-members: df_as_html 33 | 34 | 35 | .. include:: ../ejemplos/header_ejemplos_2.rst 36 | .. include:: ../ejemplos/ejemplos_reporte.rst 37 | :start-line: 3 38 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Departamento Nacional de Planeación - DNP Colombia 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | Except as contained in this notice, the name of the DNP shall not be used 22 | in advertising or otherwise to promote the sale, use or other dealings in 23 | this Software without prior written authorization from the DNP. -------------------------------------------------------------------------------- /sphinx/source/ejemplos/header_ejemplos_2.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../ejemplos/header_ejemplos.rst 2 | 3 | A continuación se presentan ejemplos de uso, el código y resultado esperado de estos. Los datos utilizados para los ejemplos corresponden a una muestra de los **Casos positivos de COVID-19 en Colombia** disponibles en el portal de `Datos Abiertos de Colombia`_, se debe aclarar que los datos fueron modificados con el propósito de presentar el alcance de las diferentes funciones de la librería. 4 | 5 | .. _Datos Abiertos de Colombia: https://www.datos.gov.co/Salud-y-Protecci-n-Social/Casos-positivos-de-COVID-19-en-Colombia/gt2j-8ykr 6 | 7 | 8 | .. code-block:: python 9 | 10 | >>> # Se importa la librería pandas para la lectura de datos 11 | >>> import pandas as pd 12 | 13 | >>> dtypes = {'ID de caso': object, 14 | >>> 'Código DIVIPOLA': object, 15 | >>> 'Codigo departamento': object, 16 | >>> 'Codigo pais':object} 17 | 18 | >>> # Lectura de archivo de datos como dataframe 19 | >>> df_datos = pd.read_excel('dataset ejemplos.xlsx', dtype=dtypes) 20 | 21 | En caso que desee utilizar los datos utilizados en los ejemplos, puede descargarlos utilizando el siguiente link. :download:`Descargar datos (6.2 MB)`. 22 | 23 | |hr| -------------------------------------------------------------------------------- /sphinx/source/introduccion.rst: -------------------------------------------------------------------------------- 1 | Introducción 2 | ============ 3 | 4 | La librería de calidad de datos tiene como objetivo principal ser una herramienta que facilite la verificación de contenido de bases de datos y dé métricas de calidad para que usuarios puedan decidir si sus bases de datos necesitan modificarse para ser utilizadas en los proyectos. La librería fue escrita en el lenguaje de programación de *Python* y puede analizar bases de datos estructurados que se conviertan en objetos *dataframe*. Contiene tres módulos principales, el módulo :ref:`leila.calidad_datos ` para analizar cualquier base de datos, el módulo :ref:`leila.datos_gov ` para conectarse con los metadatos del Portal de `Datos Abiertos de Colombia`_ y utilizar sus bases de datos, y por último el módulo de :ref:`leila.reporte ` el cual permite generar un reporte de calidad utilizando los módulos anteriores. 5 | 6 | La librería surge como resultado de un proyecto relacionado con realizar análisis descriptivos de la calidad de la información cargada al portal de Datos Abiertos de Colombia, durante el desarrollo del proyecto se identifica el interés por parte de diferentes actores en el proyecto al igual que el beneficio potencial de tener a la mano una librería que facilite describir la calidad de una base de datos, lo cual motivó a realizar la implementación de la librería. 7 | 8 | Esta página contiene toda la información relacionada con la librería, en el panel de navegación se tiene acceso a las diferentes secciones, las cuales cubren la instalación de la librería, la documentación de los módulos y funciones, ejemplos y demás información de interés. 9 | 10 | .. _Datos Abiertos de Colombia: https://www.datos.gov.co/ -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import setuptools 2 | 3 | with open("README.md", "r", encoding="utf-8") as fh: 4 | long_description = fh.read() 5 | 6 | INSTALL_REQUIRES = [ 7 | "jinja2>=3.1.0", 8 | "openpyxl>=3.1.0", 9 | "pandas>=2.0.0", 10 | "phik>=0.12.0", 11 | "requests>=2.31.0", 12 | "scipy>=1.10.0", 13 | "unidecode>=1.3.0", 14 | "xlrd>=2.0.1", 15 | "numpy>=1.24.0", 16 | ] 17 | PACKAGE_NAME = "leila" 18 | 19 | setuptools.setup( 20 | name=PACKAGE_NAME, 21 | version="0.2", 22 | author="Departamento Nacional de Planeación - DNP", 23 | author_email="ucd@dnp.gov.co", 24 | maintainer="Unidad de Científicos de Datos - UCD", 25 | maintainer_email="ucd@dnp.gov.co", 26 | description=( 27 | "Librería para medir la calidad de los datos en conjuntos " 28 | "de datos estructurados" 29 | ), 30 | long_description=long_description, 31 | long_description_content_type="text/markdown", 32 | license="MIT", 33 | keywords=[ 34 | "Python", 35 | "Calidad de datos", 36 | "UCD", 37 | "DNP", 38 | ], 39 | url="https://github.com/ucd-dnp/leila", 40 | packages=setuptools.find_packages(), 41 | include_package_data=True, 42 | install_requires=INSTALL_REQUIRES, 43 | project_urls={ 44 | "Documentación": "https://ucd-dnp.github.io/leila/", 45 | "Seguimiento de fallas": "https://github.com/ucd-dnp/leila/issues", 46 | }, 47 | classifiers=[ 48 | "License :: OSI Approved :: MIT License", 49 | "Operating System :: Microsoft :: Windows", 50 | "Operating System :: POSIX :: Linux", 51 | "Programming Language :: Python :: 3.8", 52 | "Programming Language :: Python :: 3.9", 53 | "Programming Language :: Python :: 3.10", 54 | "Programming Language :: Python :: 3.11", 55 | "Programming Language :: Python :: 3.12", 56 | ], 57 | python_requires=">=3.8", 58 | ) 59 | -------------------------------------------------------------------------------- /sphinx/source/conf.py: -------------------------------------------------------------------------------- 1 | # Configuration file for the Sphinx documentation builder. 2 | # 3 | # This file only contains a selection of the most common options. For a full 4 | # list see the documentation: 5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html 6 | 7 | # -- Path setup -------------------------------------------------------------- 8 | 9 | # If extensions (or modules to document with autodoc) are in another directory, 10 | # add these directories to sys.path here. If the directory is relative to the 11 | # documentation root, use os.path.abspath to make it absolute, like shown here. 12 | 13 | import os 14 | import sys 15 | # sys.path.insert(0, os.path.abspath('../..')) 16 | sys.path.insert(0, os.path.abspath('../../leila')) 17 | 18 | 19 | # -- Project information ----------------------------------------------------- 20 | 21 | project = 'LEILA' 22 | copyright = '2021, UCD - DNP' 23 | author = 'UCD - DNP' 24 | 25 | # The full version, including alpha/beta/rc tags 26 | release = '0.2' 27 | version = 'latest - v0.2' 28 | 29 | # -- General configuration --------------------------------------------------- 30 | 31 | # Add any Sphinx extension module names here, as strings. They can be 32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 33 | # ones. 34 | 35 | extensions = ['sphinx.ext.autodoc', 'sphinx.ext.autosectionlabel', 'sphinx_copybutton', 'sphinx_multiversion'] 36 | # extensions = ['sphinx.ext.autodoc', 'rinoh.frontend.sphinx','sphinx.ext.autosectionlabel', 'sphinx_copybutton'] 37 | 38 | copybutton_prompt_text = "myinputprompt" 39 | copybutton_prompt_text = ">>> " 40 | 41 | # copybutton_prompt_text = r">>> |\.\.\. |In \[\d*\]: | {2,5}\.\.\.: | {5,8}: " 42 | # copybutton_prompt_is_regexp = True 43 | # copybutton_only_copy_prompt_lines = False 44 | 45 | rinoh_documents = [('index', # top-level file (index.rst) 46 | 'Documentacion', # output (target.pdf) 47 | 'Documentacion librería calidad de datos', # document title 48 | 'DNP - UCD')] # document author 49 | 50 | # latex_elements = {'classoptions': ',openany', 'babel': r'\usepackage[english]{babel}'} 51 | latex_elements = {'classoptions': ',openany', 'babel': r'\usepackage[spanish]{babel}'} 52 | 53 | # Add any paths that contain templates here, relative to this directory. 54 | templates_path = ['_templates'] 55 | 56 | # The language for content autogenerated by Sphinx. Refer to documentation 57 | # for a list of supported languages. 58 | # 59 | # This is also used if you do content translation via gettext catalogs. 60 | # Usually you set "language" from the command line for these cases. 61 | language = 'es' 62 | 63 | # List of patterns, relative to source directory, that match files and 64 | # directories to ignore when looking for source files. 65 | # This pattern also affects html_static_path and html_extra_path. 66 | exclude_patterns = [] 67 | 68 | 69 | # -- Options for HTML output ------------------------------------------------- 70 | 71 | # The theme to use for HTML and HTML Help pages. See the documentation for 72 | # a list of builtin themes. 73 | html_theme = 'sphinx_rtd_theme' 74 | html_show_sourcelink = False 75 | 76 | html_context = { 77 | "display_github": False, # Integrate GitHub 78 | "github_user": "ucd-dnp", # Username 79 | "github_repo": "leila", # Repo name 80 | "github_version": "master", # Version 81 | "conf_py_path": "/source/", # Path in the checkout to the docs root 82 | } 83 | 84 | 85 | html_theme_options = { 86 | 'display_version': True, 87 | 'style_external_links' : True 88 | } 89 | 90 | 91 | # Add any paths that contain custom static files (such as style sheets) here, 92 | # relative to this directory. They are copied after the builtin static files, 93 | # so a file named "default.css" will overwrite the builtin "default.css". 94 | html_static_path = ['_static'] 95 | html_css_files = ['css/custom.css'] 96 | html_logo = '_static/image/logo_400.png' 97 | html_favicon = '_static/image/favicon.ico' 98 | 99 | from sphinx.writers.html import HTMLTranslator 100 | class PatchedHTMLTranslator(HTMLTranslator): 101 | def visit_reference(self, node): 102 | if node.get('newtab') or not (node.get('target') or node.get('internal') or 'refuri' not in node): 103 | node['target'] = '_blank' 104 | super().visit_reference(node) 105 | 106 | def setup(app): 107 | app.set_translator('html', PatchedHTMLTranslator) -------------------------------------------------------------------------------- /sphinx/source/control_de_cambios.rst: -------------------------------------------------------------------------------- 1 | Control de cambios 2 | ================== 3 | 4 | 0.2 (2021-12-15) 5 | ---------------- 6 | 7 | Agregado 8 | ~~~~~~~~ 9 | - Se agrega sección *Columnas en este conjunto de datos* en reportes generados para conjuntos del portal de `Datos Abiertos Colombia`_ mediante la función :py:meth:`reporte.generar_reporte` del módulo :ref:`reporte `. 10 | - Se agregó la función :py:meth:`datos_gov.DatosGov.metadatos` para consultar los metadatos del conjunto de datos de interés publicado en el portal de `Datos Abiertos Colombia`_. 11 | - Se agregó la función :py:meth:`datos_gov.DatosGov.to_dataframe` para retornar el conjunto de datos descargado del portal `Datos Abiertos Colombia`_ en formato ``pandas.DataFrame`` 12 | 13 | Cambiado 14 | ~~~~~~~~ 15 | 16 | Código 17 | ++++++ 18 | - Se reestructuró el módulo ``datos_gov`` en la clase :py:class:`datos_gov.DatosGov` 19 | - Se agregó parámetro ``filtro`` dentro de la función :py:meth:`datos_gov.DatosGov.tabla_inventario` del módulo :ref:`datos_gov `, que permite filtrar por palabras clave. 20 | - Se reemplazó el parámetro ``df`` por ``datos`` dentro de la función :py:meth:`reporte.generar_reporte` 21 | - Se agregó soporte para lectura directa de archivos tipo ``.xlsx``, y ``.csv`` por parte de la clase :py:class:`calidad_datos.CalidadDatos` 22 | - Se agregó soporte para lectura directa de objetos tipo :py:class:`leila.DatosGov() ` por parte de la clase :py:class:`calidad_datos.CalidadDatos` 23 | - Se agregó parámetro ``especificas`` dentro de la función :py:meth:`reporte.generar_reporte`, que permite personalizar el reporte automático. 24 | - Se agregó el parámetro ``limite_filas`` a las funciones :py:meth:`CantidadDuplicados ` y :py:meth:`EmparejamientoDuplicados ` de la clase 'CalidadDatos'. Este parámetro define el límite de filas que se tendrá en cuenta al calcular los duplicados por columnas (el valor por defecto es 30.000). 25 | - Se ajustó el código de los siguientes métodos de la clase 'CalidadDatos', para no copiar el conjunto de datos de entrada y evitar problemas de memoria: CorrelacionCategoricas, DescripcionNumericas, DescripcionCategoricas, CantidadDuplicados, EmparejamientoDuplicados. 26 | - Se adecuó el código de la librería al estilo PEP-8. 27 | - Se ajustó el código del método 'TipoColumnas' de la clase CalidadDatos para mejorar los tiempos de ejecución. 28 | - Se adecuó el código de la clase CalidadDatos para que el tipo específico y el tipo general de las columnas se calculen cuando se crea la clase y no cuando se ejecutan los métodos que hacen uso de los tipos. 29 | - Los módulos 'calidad_datos' y 'reporte' tendrán el nuevo parámetro ``castDatos``, el cual indica si se desean convertir las columnas al mejor tipo de columna, según la función 'convert_dtypes' de la librería Pandas. Este parámetro remplazará a ``castNumero``, el cual será deprecado en un futuro. 30 | 31 | Repositorio 32 | +++++++++++ 33 | - Se redactó guía en GitHub en español para reportar issues en la librería 34 | - Se redactó guía en español para realizar colaboraciones y adiciones a la librería en GitHub 35 | - Se añaden nuevos ejemplos de uso de la librería en la carpeta de `ejemplos`_ 36 | - Se actualiza documentación de LEILA con respecto a los nuevos cambios. 37 | 38 | Memoria y tiempo de ejecución 39 | +++++++++++++++++++++++++++++ 40 | - Se mejoró los tiempos de ejecución para las funciones :py:meth:`CantidadDuplicados ` y :py:meth:`EmparejamientoDuplicados ` de la clase :py:class:`calidad_datos.CalidadDatos` 41 | - Se redujeron los tiempos de ejecución generales y los requisitos de memoria. 42 | - Las funciones de la librería se pueden ejecutar para conjuntos de datos más grandes 43 | - Las funciones generan resultados más rápidos para los mismos conjuntos de datos 44 | 45 | Wiki de LEILA 46 | ~~~~~~~~~~~~~ 47 | El `Wiki de LEILA`_ se encuentra en el repositorio web de GitHub y contiene la siguiente información: 48 | 49 | - Proceso de trabajo de los desarrolladores de LEILA 50 | - Guía para hacer preguntas de uso, reportar errores y solicitar nuevas características para LEILA 51 | - Guía para hacer contribuciones y pull-request a LEILA 52 | - Reglas de comunidad 53 | 54 | Obsoleto 55 | ~~~~~~~~ 56 | - Ya no es necesario el parámetro *token* dentro de las funciones :py:meth:`datos_gov.DatosGov.cargar_base` y :py:meth:`reporte.generar_reporte` 57 | 58 | Borrado 59 | ~~~~~~~ 60 | - Se eliminó función ``filtrar_tabla()`` del módulo :ref:`datos_gov ` 61 | 62 | Arreglado 63 | ~~~~~~~~~ 64 | - Se corrigieron errores generados por conflictos de librerías de soporte al instalar la librería 65 | 66 | 67 | .. _Datos Abiertos Colombia: https://www.datos.gov.co/ 68 | .. _Wiki de LEILA: https://github.com/ucd-dnp/leila/wiki 69 | .. _ejemplos: https://github.com/ucd-dnp/leila/tree/master/ejemplos -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LEILA - Librería de calidad de datos 2 | 3 | ![screenshot](recursos/leila.png "LEILA") 4 | 5 | 6 | 7 | [![PyPI version fury.io](https://badge.fury.io/py/leila.svg)](https://pypi.org/project/leila/) [![PyPI pyversions](https://img.shields.io/pypi/pyversions/leila.svg)](https://pypi.org/project/leila/) 8 | [![PyPI license](https://img.shields.io/pypi/l/leila.svg)](https://pypi.org/project/leila/) [![Downloads](https://pepy.tech/badge/leila)](https://pepy.tech/project/leila) [![GitHub forks](https://img.shields.io/github/forks/ucd-dnp/leila.svg?style=social&label=Fork&maxAge=2592000)](https://github.com/ucd-dnp/leila/) 9 | 10 | ## Descripción 11 | 12 | La librería de calidad de datos tiene como objetivo principal ser una herramienta que facilite la verificación de contenido de bases de datos y dé métricas de calidad para que usuarios puedan decidir si sus bases de datos necesitan modificarse para ser utilizadas en los proyectos. La librería fue escrita en el lenguaje de programación de Python y puede analizar bases de datos estructurados que se conviertan en objetos tipo pandas.DataFrame. Contiene tres módulos principales, el módulo Calidad Datos para analizar cualquier base de datos, el módulo Datos gov para conectarse con los metadatos del Portal de [Datos Abiertos de Colombia](https://www.datos.gov.co/) y utilizar sus bases de datos, y por último el módulo Reporte el cual permite generar un reporte de calidad utilizando los módulos anteriores. 13 | 14 | La librería surge como resultado de un proyecto relacionado con realizar análisis descriptivos de la calidad de la información cargada al portal de Datos Abiertos de Colombia, durante el desarrollo del proyecto se identifica el interés por parte de diferentes actores en el proyecto al igual que el beneficio potencial de tener a la mano una librería que facilite describir la calidad de una base de datos, lo cual motivó a realizar la implementación de la librería. 15 | 16 | - A continuación podrá consultar la siguiente información: 17 | - [Ejemplo](#ejemplo) 18 | - [Documentación](#documentaci%C3%B3n) 19 | - [Instalación](#instalaci%C3%B3n) 20 | - [Control de cambios](#control-de-cambios) 21 | - [Contribuciones](#contribuciones) 22 | - [Licencia](#licencia) 23 | - [Contacto](#contacto) 24 | 25 | ## Ejemplo 26 | 27 | La librería permite generar un reporte de calidad de datos el cual contiene información descriptiva del dataframe analizado, a continuación se presenta el código requerido para generar un reporte a partir de un archivo en Excel en formato .xlsx. 28 | 29 | ``` python 30 | from leila.reporte import generar_reporte 31 | 32 | generar_reporte(datos='datosDeInteres.xlsx') 33 | ``` 34 | 35 | ![screenshot](https://raw.githubusercontent.com/ucd-dnp/leila/master/recursos/vista_reporte.gif "Reporte") 36 | 37 | ## Documentación 38 | 39 | La librería cuenta con una documentación que detalla las funciones que la conforman, al igual que ejemplos de uso y demás información de interés relacionada con esta, para acceder a la documentación siga el siguiente link: 40 | 41 | [Documentación - LEILA - Librería de calidad de datos.](https://ucd-dnp.github.io/leila/) 42 | 43 | ## Instalación 44 | 45 | Para la instalación de la librería se recomienda utilizar el gestor de paquetes ``pip``, por buenas prácticas se sugiere antes de la instalación crear un entorno virtual que permita aislar las librerías y evitar conflictos de versiones con el entorno de desarrollo base del computador. 46 | 47 | ``` linux 48 | pip install leila 49 | ``` 50 | 51 | De manera alterna también puede utilizar el gestor de paquetes ``conda``. 52 | 53 | ``` 54 | conda install -c ucd-dnp -c conda-forge leila 55 | ``` 56 | ## Control de cambios 57 | 58 | Para ver todos los cambios en las versiones de `LEILA` ver el archivo [changelog](https://github.com/ucd-dnp/leila/wiki/Changelog) 59 | ## Contribuciones a LEILA 60 | 61 | Todas las contribuciones, reportes de errores, corrección de errores, las mejoras de la documentación y las ideas son bienvenidas. 62 | 63 | Puede encontrar una descripción detallada de cómo contribuir en la [Wiki de LEILA](https://github.com/ucd-dnp/leila/wiki) 64 | 65 | También lo invitamos a revisar el [:calendar: Tablero **TODO** de LEILA](https://github.com/users/ucd-dnp/projects/3), donde hay una serie de temas listados en los que el equipo UCD se encuentra trabajando. 66 | 67 | ## Licencia [![MIT license](https://img.shields.io/badge/License-MIT-blue.svg)](https://lbesson.mit-license.org/) 68 | 69 | ### **MIT License** 70 | 71 | La librería LEILA - Calidad de datos se encuentra publicada bajo la licencia MIT
    72 | Copyleft (c) 2020 - 2021 Departamento Nacional de Planeación - DNP Colombia 73 | 74 | Para mayor información puede consultar el archivo de [Licencia](https://github.com/ucd-dnp/leila/blob/master/LICENSE) 75 | 76 | ## Contacto 77 | 78 | Para comunicarse con la Unidad de Científicos de Datos (UCD) de la Dirección de Desarrollo Digital (DDD) del DNP, lo puede hacer mediante el correo electrónico ucd@dnp.gov.co 79 | -------------------------------------------------------------------------------- /sphinx/source/ejemplos/ejemplos_reporte.rst: -------------------------------------------------------------------------------- 1 | Ejemplos - Reporte 2 | ======================== 3 | 4 | Generando un reporte 5 | -------------------- 6 | 7 | Crea un reporte de calidad de datos en formato HTML. Ver documentación :py:meth:`reporte.generar_reporte` 8 | 9 | En este ejemplo generaremos el reporte a partir de un api_id, este caso corresponde a los casos positivos de COVID-19 reportados en Colombia en el Portal de Datos Abiertos. 10 | 11 | Teniendo en cuenta que se trata de un conjunto de datos con muchos registros, usamos el argumento limite_filas para 12 | limitar la descarga de información a solo los primeros 1.000 registros. 13 | 14 | El título del reporte será 'Casos positivos de COVID-19 en Colombia (primeros 1000 registros)' y será guardado con el nombre reporte_calidad_COVID.html 15 | 16 | 17 | .. code-block:: python 18 | 19 | >>> # Se importa la función generar_reporte del módulo de reporte 20 | >>> from leila.reporte import generar_reporte 21 | 22 | >>> generar_reporte(datos="gt2j-8ykr", 23 | >>> titulo='Casos positivos de COVID-19 en Colombia (primeros 1000 registros)', 24 | >>> archivo='ejemplo_reporte__API_datos_abiertos.html', 25 | >>> limite_filas=1000) 26 | 27 | -------------------------------------------------------------------------------------------- 28 | No hay columnas duplicadas 29 | -------------------------------------------------------------------------------------------- 30 | Se ha generado el reporte "ejemplo_reporte__API_datos_abiertos.html" 31 | 09:00:11 AM (00 min 6 seg) 32 | -------------------------------------------------------------------------------------------- 33 | 34 | Personalizar secciones 35 | ~~~~~~~~~~~~~~~~~~~~~~ 36 | Si desea excluir una sección del reporte lo puede hacer mediante el parámetro secciones. 37 | En el siguiente ejemplo se excluyó del reporte la sección 'correlaciones', y de la sección 'Estadísticas específicas' 38 | solo se incluyeron las pestañas 'Tipo de las columnas' y 'Frecuencia de categorías' 39 | 40 | 41 | .. code-block:: python 42 | 43 | >>> # Se importa la función generar_reporte del módulo de reporte 44 | >>> from leila.reporte import generar_reporte 45 | 46 | >>> generar_reporte(datos="bign-27m7", 47 | >>> titulo="Reporte visas", 48 | >>> archivo='ejemplo_reporte__secciones.html', 49 | >>> secciones={'generales':True, 'muestra_datos': True, 'correlaciones': False, 50 | >>> 'especificas': ['tipo', 'frecuencias']}) 51 | 52 | -------------------------------------------------------------------------------------------- 53 | El conjunto de datos no tiene columnas numéricas 54 | -------------------------------------------------------------------------------------------- 55 | Se ha generado el reporte "ejemplo_reporte__secciones.html" 56 | 09:00:20 AM (00 min 0 seg) 57 | -------------------------------------------------------------------------------------------- 58 | 59 | 60 | Reporte usando archivos XLSX, CSV o DataFrames 61 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 62 | También se puede generar el reporte a partir de un dataframe o indicando la ruta de un archivo XLSX o CSV. Para esto solo se requiere cambiar el parámetro datos. 63 | 64 | 65 | .. code-block:: python 66 | 67 | >>> # Se importa la función generar_reporte del módulo de reporte 68 | >>> from leila.reporte import generar_reporte 69 | 70 | >>> # Se llama la función para generar el reporte 71 | >>> generar_reporte(datos="dataset ejemplos.xlsx", 72 | >>> titulo='Reporte de prueba archivo XLSX', 73 | >>> archivo='ejemplo_reporte__archivo_XLSX.html') 74 | 75 | -------------------------------------------------------------- 76 | Se ha generado el reporte "ejemplo_reporte__archivo_XLSX.html" 77 | 09:00:38 AM (00 min 20 seg) 78 | -------------------------------------------------------------- 79 | 80 | 81 | .. code-block:: python 82 | 83 | >>> # Se importa la función generar_reporte del módulo de reporte 84 | >>> from leila.reporte import generar_reporte 85 | 86 | >>> # Se llama la función para generar el reporte 87 | >>> generar_reporte(datos=df_datos, 88 | >>> titulo='Perfilamiento datos COVID-19 - Colombia', 89 | >>> archivo='ejemplo_reporte__dataframe.html') 90 | 91 | -------------------------------------------------------------- 92 | Se ha generado el reporte "ejemplo_reporte__dataframe.html" 93 | 09:01:22 AM (00 min 22 seg) 94 | -------------------------------------------------------------- 95 | 96 | 97 | .. figure:: https://github.com/ucd-dnp/leila/blob/gh-pages/sphinx/source/_static/image/vista_reporte.gif?raw=true 98 | :align: center 99 | :alt: Ejemplo de reporte 100 | :figclass: align-center 101 | 102 | Ejemplo de reporte -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog *LEILA* 2 | 3 | Todos los cambios importantes de esta librería serán documentados en este archivo. 4 | 5 | ## 0.2.0 (2021-12-15) 6 | ### Agregado 7 | - Se agrega sección ***Columnas en este conjunto de datos*** en reportes generados para conjuntos del portal de [Datos Abiertos Colombia ](https://www.datos.gov.co/) mediante la función [generar_reporte()](https://ucd-dnp.github.io/leila/versiones/master/funciones/reporte.html#reporte.generar_reporte) del módulo *reporte*. 8 | - Se agregó la función [DatosGov.metadatos()](https://ucd-dnp.github.io/leila/versiones/master/funciones/datos_gov.html#datos_gov.DatosGov.metadatos) para consultar los metadatos del conjunto de datos de interés publicado en el portal de [Datos Abiertos Colombia ](https://www.datos.gov.co/). 9 | - Se agregó la función [DatosGov.to_dataframe()](https://ucd-dnp.github.io/leila/versiones/master/funciones/datos_gov.html#datos_gov.DatosGov.to_dataframe) para retornar el conjunto de datos descargado del portal [Datos Abiertos Colombia ](https://www.datos.gov.co/) en formato pandas.DataFrame 10 | 11 | ### Cambiado 12 | #### Código 13 | 14 | * Se reestructuró el modulo [datos_gov](https://ucd-dnp.github.io/leila/versiones/master/funciones/datos_gov.html#) en la clase [DatosGov()](https://ucd-dnp.github.io/leila/versiones/master/funciones/datos_gov.html#datos_gov.DatosGov) 15 | * Se agregó parámetro *filtro* dentro de la función [tabla_inventario()](https://ucd-dnp.github.io/leila/versiones/master/funciones/datos_gov.html#datos_gov.DatosGov.tabla_inventario) del módulo [datos_gov](https://ucd-dnp.github.io/leila/versiones/master/funciones/datos_gov.html#) , que permite filtrar por palabras clave. 16 | * Se reemplazó el parámetro *df* por *datos* dentro de la función [generar_reporte()](https://ucd-dnp.github.io/leila/versiones/master/funciones/reporte.html#reporte.generar_reporte) 17 | * Se agregó soporte para lectura directa de archivos tipo '.xlsx', y '.csv' por parte de la clase [CalidadDatos()](https://ucd-dnp.github.io/leila/versiones/master/funciones/calidad_datos.html#calidad_datos.CalidadDatos) 18 | * Se agregó soporte para lectura directa de objetos tipo [leila.DatosGov()](https://ucd-dnp.github.io/leila/versiones/master/funciones/datos_gov.html#datos_gov.DatosGov) por parte de la clase [CalidadDatos()](https://ucd-dnp.github.io/leila/versiones/master/funciones/calidad_datos.html#calidad_datos.CalidadDatos) 19 | * Se agregó parámetro *especificas* dentro de la función [generar_reporte()](https://ucd-dnp.github.io/leila/versiones/master/funciones/reporte.html#reporte.generar_reporte), que permite personalizar el reporte automático. 20 | 21 | - Se agregó el parámetro 'limite_filas' a los métodos 'CantidadDuplicados' y 'EmparejamientoDuplicados' de la clase 'CalidadDatos'. Este parámetro define el límite de filas que se tendrá en cuenta al calcular los duplicados por columnas (el valor por defecto es 30.000) 22 | - Se ajustó el código de los siguientes métodos de la clase 'CalidadDatos', para no copiar el conjunto de datos de entrada y evitar problemas de memoria: CorrelacionCategoricas, DescripcionNumericas, DescripcionCategoricas, CantidadDuplicados, EmparejamientoDuplicados 23 | - Se adecuó el código de la librería al estilo PEP-8 24 | - Se ajustó el código del método 'TipoColumnas' de la clase CalidadDatos para mejorar los tiempos de ejecución 25 | - Se adecuó el código de la clase CalidadDatos para que el tipo específico y el tipo general de las columnas se calculen cuando se crea la clase y no cuando se ejecutan los métodos que hacen uso de los tipos 26 | - Los módulos "calidad_datos" y "reporte" tendrán el nuevo parámetro "castDatos", el cual indica si se desean convertir las columnas al mejor tipo de columna, según la función 'convert_dtypes' de la librería Pandas. Este parámetro remplazará a "castNumero", el cual será deprecado en un futuro 27 | 28 | #### Repositorio 29 | - Se redactó guía en GitHub en español para reportar issues en la librería 30 | - Se redactó guía en español para realizar colaboraciones y adiciones a la librería en GitHub 31 | - Se añaden nuevos ejemplos de uso de la librería en la carpeta de [ejemplos](https://github.com/ucd-dnp/leila/tree/master/ejemplos) 32 | - Se actualiza documentación de LEILA con respecto a los nuevos cambios. 33 | 34 | #### Memoria y tiempo de ejecución 35 | 36 | * Se mejoró los tiempos de ejecución para las funciones 'CantidadDuplicados' y 'EmparejamientoDuplicados' de la clase 'CalidadDatos' 37 | 38 | - Se redujeron los tiempos de ejecución generales y los requisitos de memoria. 39 | - Las funciones de la librería se pueden ejecutar para conjuntos de datos más grandes 40 | - Las funciones generan resultados más rápidos para los mismos conjuntos de datos 41 | 42 | ### Wiki de LEILA 43 | El [Wiki de LEILA](https://github.com/ucd-dnp/leila/wiki) se encuentra en el repositorio web de GitHub y contiene la siguiente información: 44 | 45 | - Proceso de trabajo de los desarrolladores de LEILA 46 | - Guía para hacer preguntas de uso, reportar errores y solicitar nuevas características para LEILA 47 | - Guía para hacer contribuciones y pull-request a LEILA 48 | - Reglas de comunidad 49 | 50 | ### Obsoleto 51 | 52 | * Ya no es necesario el parámetro *token* dentro de las funciones [cargar_base()]() y en [generar_reporte()]() 53 | 54 | ### Borrado 55 | 56 | * Se eliminó función [filtrar_tabla()](https://ucd-dnp.github.io/leila/versiones/v0.1b/funciones/datos_gov.html#datos_gov.filtrar_tabla) del módulo [datos_gov()](https://ucd-dnp.github.io/leila/versiones/master/funciones/datos_gov.html#) 57 | 58 | ### Arreglado 59 | - Se corrigieron errores generados por conflictos de librerías de soporte al instalar la librería 60 | -------------------------------------------------------------------------------- /leila/datos_gov.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import warnings 4 | import pandas as pd 5 | import requests 6 | from unidecode import unidecode 7 | import re 8 | import datetime 9 | 10 | 11 | class DatosGov: 12 | """ 13 | Clase para cargar conjuntos de datos del portal de `datos.gov.co` y \ 14 | descargar los metadatos de dichos conjuntos. 15 | """ 16 | 17 | def __init__(self): 18 | self._dominio = "https://www.datos.gov.co/resource/" 19 | self._meta = "https://www.datos.gov.co/api/views/" 20 | self.__metadatos = None 21 | self.datos = None 22 | self._DIC_RENAME = { 23 | "uid": "numero_api", 24 | "name": "nombre", 25 | "description": "descripcion", 26 | "owner": "dueno", 27 | "type": "tipo", 28 | "category": "categoria", 29 | "tags": "terminos_clave", 30 | "url": "url", 31 | "creation_date": "fecha_creacion", 32 | "last_data_updated_date": "fecha_actualizacion", 33 | "informacindedatos_frecuenciadeactualizacin": "actualizacion_frecuencia", 34 | "row_count": "filas", 35 | "column_count": "columnas", 36 | "contact_email": "correo_contacto", 37 | "license": "licencia", 38 | "attribution": "entidad", 39 | "attribution_link": "entidad_url", 40 | "informacindelaentidad_sector": "entidad_sector", 41 | "informacindelaentidad_departamento": "entidad_departamento", 42 | "informacindelaentidad_orden": "entidad_orden", 43 | "informacindelaentidad_reaodependencia": "entidad_dependencia", 44 | "informacindelaentidad_municipio": "entidad_municipio", 45 | "informacindedatos_idioma": "idioma", 46 | "informacindedatos_coberturageogrfica": "cobertura", 47 | "publication_stage": "base_publica", 48 | } 49 | 50 | def cargar_base(self, api_id, limite_filas=1000000000): 51 | """ 52 | Permite descargar un conjunto de datos del portal de datos.gov.co \ 53 | dado su identificador `api_id` en el portal. \ 54 | :ref:`Ver ejemplo `. 55 | 56 | .. warning:: 57 | Al descargar una base de datos utilizando el API de Socrata, \ 58 | esta omitirá cualquier columna que no contenga registros, lo cual \ 59 | puede generar inconsistencias con la información descrita en el \ 60 | portal de datos abiertos. 61 | 62 | :param api_id: Identificador único del conjunto de datos registrado \ 63 | en el API de Socrata. 64 | :type api_id: str 65 | :param limite_filas: Número máximo de registros a descargar del \ 66 | conjunto de datos. Valor por defecto: `1000000000`. 67 | :type limite_filas: int, opcional 68 | :return: (DatosGov) Objeto del tipo DatosGov, que contiene la \ 69 | información del conjunto de datos. Para obtener el DataFrame \ 70 | revise la función to_dataframe(). 71 | """ 72 | url = f"{self._dominio}{api_id}.csv?$limit={100}" 73 | # Solo se leen 100 filas para estimar tipo de datos 74 | temp = pd.read_csv(url) 75 | # cols que pueden contener fecha 76 | col_objs = list(temp.select_dtypes(object)) 77 | url = f"{self._dominio}{api_id}.csv?$limit={limite_filas}" 78 | self.datos = pd.read_csv(url, parse_dates=col_objs) 79 | # Almacenar los metadatos 80 | query = requests.get(f"{self._meta}{api_id}.json") 81 | self.__metadatos = dict(query.json()) 82 | if "cachedContents" in self.__metadatos["columns"][0] and "count" in self.__metadatos["columns"][0]["cachedContents"]: 83 | self.__metadatos["n_rows"] = int( 84 | self.__metadatos["columns"][0]["cachedContents"]["count"] 85 | ) 86 | else: 87 | self.__metadatos["n_rows"] = "NA" 88 | if "columns" in self.__metadatos: 89 | self.__metadatos["n_cols"] = len(self.__metadatos["columns"]) 90 | else: 91 | self.__metadatos["n_cols"] = "NA" 92 | query.close() 93 | return self 94 | 95 | def to_dataframe(self): 96 | """ 97 | Retorna el conjunto de datos descargado del portal de datos \ 98 | abiertos (datos.gov.co) en formato pandas.DataFrame. 99 | 100 | :return: (pandas.DataFrame) conjunto de datos en DataFrame. 101 | """ 102 | return self.datos 103 | 104 | def metadatos(self): 105 | """ 106 | Retorna los metadatos del conjunto de datos descargado del \ 107 | portal de datos abiertos (datos.gov.co) en un diccionario de Python. 108 | 109 | :return: (dict) Diccionario con los metadados del conjunto de datos. 110 | """ 111 | return self.__renombrar_metadatos() 112 | 113 | def tabla_inventario(self, filtro=None, limite_filas=10000000000): 114 | """ 115 | Función que se conecta con el API de Socrata para el portal de \ 116 | datos.gov.co y retorna el inventario de datos disponible. \ 117 | :ref:`Ver ejemplo ` 118 | 119 | :param filtro: Permite filtar la tabla de inventario de datos \ 120 | tomando como referencia las columnas presentes en la tabla, \ 121 | mediante un diccionario de datos del tipo {'nombre_columna': \ 122 | ['valor buscado1', 'valor buscado 2']}. Para mayor información \ 123 | consulte: (REVISAR) 124 | :type filtro: dict, opcional. 125 | :param limite_filas: Limite de registros a descargar del inventario \ 126 | de datos. Por defecto: `10000000000`. 127 | :type limite_filas: int, opcional. 128 | :return: (pandas.DataFrame) Dataframe con la información de los datos \ 129 | disponibles en el portal datos.gov.co. 130 | """ 131 | url = f"{self._dominio}uzcf-b9dh.csv?$limit={limite_filas}" 132 | tabla = pd.read_csv( 133 | url, 134 | usecols=list(self._DIC_RENAME.keys()), 135 | parse_dates=["last_data_updated_date", "creation_date"], 136 | ) 137 | tabla.rename(columns=self._DIC_RENAME, inplace=True) 138 | tabla.replace( 139 | { 140 | "base_publica": {"published": "Si", "unpublished": "No"}, 141 | "tipo": { 142 | "dataset": "conjunto de datos", 143 | "federated_href": "enlace externo", 144 | "href": "enlace externo", 145 | "map": "mapa", 146 | "chart": "grafico", 147 | "filter": "vista filtrada", 148 | "file": "archivo o documento", 149 | "visualization": "visualizacion", 150 | "story": "historia", 151 | "datalens": "lente de datos", 152 | "form": "formulario", 153 | "calendar": "calendario", 154 | "invalid_datatype": "tipo_invalido", 155 | }, 156 | }, 157 | inplace=True, 158 | ) 159 | if filtro is not None: 160 | tabla = self.__filtrar_tabla(tabla, filtro) 161 | 162 | return tabla 163 | 164 | def __filtrar_tabla(self, data, filtros): 165 | # valores del filtro 166 | col_filtros = set(filtros.keys()) 167 | str_cols = list( 168 | set(data.dtypes[data.dtypes == object].index.tolist()) 169 | & col_filtros 170 | ) 171 | num_cols = list(set(["filas", "columnas"]) & col_filtros) 172 | date_cols = list( 173 | set(["fecha_creacion", "fecha_actualizacion"]) & col_filtros 174 | ) 175 | 176 | if not len(str_cols + num_cols + date_cols): 177 | raise KeyError( 178 | "La tabla de inventario no tiene columna(s) con el nombre " 179 | f"{list(filtros.keys())}. Las llaves del diccionario solo " 180 | f" pueden tomar los siguientes valores:{list(data.columns)}" 181 | ) 182 | # Buscar en columnas string 183 | if len(str_cols) > 0: 184 | for c in str_cols: 185 | if not isinstance(filtros[c], list): 186 | raise TypeError( 187 | "Los valores buscados deben ser tipo lista. Por " 188 | "ejemplo, para buscar 'moneda' en el nombre de los " 189 | "conjuntos de datos debe pasar filtro = " 190 | "{'nombre':['moneda']}" 191 | ) 192 | value = [self.__normalizar_string(v) for v in filtros[c]] 193 | p = r"\b(?:{})\b".format("|".join(map(re.escape, value))) 194 | temp = data[c].apply(self.__normalizar_string) 195 | data = data[temp.str.contains(p)] 196 | if not data.shape[0]: 197 | warnings.warn( 198 | "No se encontró ningun registro con los valores: " 199 | f"{value} en la columna: {c}" 200 | ) 201 | return data 202 | 203 | # buscar limites en columas/filas numericas 204 | if len(num_cols) > 0: 205 | for c in num_cols: 206 | if not isinstance(filtros[c], list) or len(filtros[c]) != 2: 207 | raise TypeError( 208 | f"Para filtrar la tabla de inventario por [{c}] debe " 209 | "pasar una lista de dos posiciones que representan el " 210 | f"valor mínimo y máximo de {c} [v_min, v_max] por el " 211 | "que desea filtrar." 212 | ) 213 | limites = filtros[c] 214 | data = data[(data[c] >= limites[0]) & (data[c] <= limites[1])] 215 | if not data.shape[0]: 216 | return data 217 | 218 | # buscar en columnas de fecha 219 | if len(date_cols) > 0: 220 | for c in date_cols: 221 | if not isinstance(filtros[c], list) or len(filtros[c]) != 2: 222 | raise TypeError( 223 | f"Para filtrar la tabla de inventario por [{c}] debe " 224 | "pasar una lista de dos posiciones que representan el " 225 | f"la fecha inicial y fecha final de consulta " 226 | "[fecha_inicial, fecha_final]. Por ejemplo, filtro = " 227 | "{'fecha_creacion': ['2019-01-01', '2020-02-20']} " 228 | ) 229 | 230 | limites = filtros[c] 231 | data = data[(data[c] >= limites[0]) & (data[c] <= limites[1])] 232 | if not data.shape[0]: 233 | return data 234 | 235 | return data 236 | 237 | def __normalizar_string(self, texto): 238 | return unidecode(texto.lower()) 239 | 240 | def __renombrar_metadatos(self): 241 | # Crear diccionario para renombrar algunos metadatos 242 | dic_rename = { 243 | 'id': 'numero_api', 244 | 'name': 'nombre', 245 | 'description': 'descripcion', 246 | 'assetType': 'tipo', 247 | 'attributionLink': 'url', 248 | 'category': 'categoria', 249 | 'createdAt': 'fecha_creacion', 250 | 'viewCount': 'numero_vistas', 251 | 'downloadCount': 'numero_descargas', 252 | 'licenseId': 'licencia', 253 | 'publicationDate': 'fecha_publicacion', 254 | 'publicationStage': 'base_publica', 255 | 'rowsUpdatedAt': 'fecha_actualizacion', 256 | 'n_rows': 'numero_filas', 257 | 'n_cols': 'numero_columnas' 258 | } 259 | 260 | # Crear nuevo diccionario con algunos valores renombrados de metadatos 261 | dic_metadatos = {} 262 | dic_metadatos = {v: self.__metadatos[k] if k in list(self.__metadatos.keys()) else "NA" for (k, v) in dic_rename.items()} 263 | 264 | # Crear valores de fecha (a partir de integers) 265 | dic_metadatos['fecha_creacion'] = datetime.datetime.fromtimestamp(dic_metadatos['fecha_creacion']).strftime('%Y-%m-%d') 266 | dic_metadatos['fecha_publicacion'] = datetime.datetime.fromtimestamp(dic_metadatos['fecha_publicacion']).strftime('%Y-%m-%d') 267 | dic_metadatos['fecha_actualizacion'] = datetime.datetime.fromtimestamp(dic_metadatos['fecha_actualizacion']).strftime('%Y-%m-%d') 268 | 269 | # Agregar licencias 270 | if 'license' in self.__metadatos and 'name' in self.__metadatos['license']['name']: 271 | dic_metadatos['licencia'] = self.__metadatos['license']['name'] 272 | else: 273 | dic_metadatos['licencia'] = "NA" 274 | 275 | if 'license' in self.__metadatos and 'termsLink' in self.__metadatos['license']: 276 | dic_metadatos['licencia_url'] = self.__metadatos['license']['termsLink'] 277 | else: 278 | dic_metadatos['licencia_url'] = "NA" 279 | 280 | # # Agregar filas y columnas 281 | # dic_metadatos["filas"] = self.__metadatos['n_rows'] 282 | # dic_metadatos["columnas"] = self.__metadatos['n_cols'] 283 | 284 | # Diccionario para renombrar metadatos de 'Información de la Entidad' 285 | entidad_info_nombres = { 286 | 'entidad': 'Nombre de la Entidad', 287 | 'entidad_municipio': 'Municipio', 288 | 'entidad_sector': 'Sector', 289 | 'entidad_departamento': 'Departamento', 290 | 'entidad_orden': 'Orden', 291 | 'entidad_dependencia': 'Área o dependencia', 292 | } 293 | 294 | # Diccionario para renombrar metadatos de 'Información de Datos' 295 | entidad_datos_nombres = { 296 | 'cobertura': 'Cobertura Geográfica', 297 | 'idioma': 'Idioma', 298 | 'frecuencia_actualizacion': 'Frecuencia de Actualización' 299 | } 300 | 301 | # Crear diccionarios reducidos de 'Información de la Entidad' e 'Información de Datos' 302 | dic_info_entidad = self.__metadatos['metadata']['custom_fields']['Información de la Entidad'] 303 | dic_info_datos = self.__metadatos['metadata']['custom_fields']['Información de Datos'] 304 | 305 | # Agregar información renombrada a diccionario de metadatos 306 | for k, v in entidad_info_nombres.items(): 307 | if v in dic_info_entidad: 308 | dic_metadatos[k] = dic_info_entidad[v] 309 | else: 310 | dic_metadatos[k] = "NA" 311 | 312 | for k, v in entidad_datos_nombres.items(): 313 | if v in dic_info_datos: 314 | dic_metadatos[k] = dic_info_datos[v] 315 | else: 316 | dic_metadatos[k] = "NA" 317 | 318 | 319 | # Agregar dueño 320 | if 'owner' in self.__metadatos and 'displayName' in self.__metadatos['owner']: 321 | dic_metadatos['dueno'] = self.__metadatos['owner']['displayName'] 322 | else: 323 | dic_metadatos['dueno'] = "NA" 324 | 325 | # Diccionario de columnas 326 | dic_c = {} 327 | 328 | # Agregar cada columna renombrada al diccionario de columnas 329 | for c in self.__metadatos['columns']: 330 | name = c["name"] 331 | dic_c[name] = { 332 | 'tipo': c['dataTypeName'], 333 | 'descripcion': c['description'], 334 | 'nombre_df': c['fieldName'] 335 | } 336 | 337 | # Agergar diccionario de columnas a diccionario de metadatos 338 | dic_metadatos["columnas"] = dic_c 339 | 340 | return dic_metadatos -------------------------------------------------------------------------------- /sphinx/source/ejemplos/ejemplos_calidad_datos.rst: -------------------------------------------------------------------------------- 1 | Ejemplos - Calidad datos 2 | ======================== 3 | 4 | 5 | .. code-block:: python 6 | 7 | >>> # Se importar la clase CalidadDatos del módulo calidad_datos 8 | >>> from leila.calidad_datos import CalidadDatos 9 | 10 | >>> # Se crea un objeto de la clase CalidadDatos con los datos de interés 11 | >>> ruta_covid = "dataset ejemplos.xlsx" 12 | >>> datos_covid = CalidadDatos(ruta_covid) 13 | 14 | 15 | Tabla de resumen 16 | ---------------- 17 | 18 | El método :py:meth:`CalidadDatos.Resumen` calcula varias estadísticas que dan una primera impresión del conjunto de datos. 19 | 20 | Estas métricas incluyen el número de filas y columnas; número de columnas de distintos tipos; número de filas y columnas repetidas (duplicadas); columnas con muchos datos faltantes o extremos; peso del conjunto de datos 21 | 22 | 23 | .. code-block:: python 24 | 25 | >>> # Calcular la tabla de resumen con el método "Resumen" 26 | >>> resumen = datos_covid.Resumen() 27 | 28 | >>> # Visualizar la tabla de resumen 29 | >>> resumen 30 | 31 | Número de filas 65616 32 | Número de columnas 25 33 | Columnas numéricas 3 34 | Columnas de texto 16 35 | Columnas booleanas 0 36 | Columnas de fecha 6 37 | Otro tipo de columnas 0 38 | Número de filas repetidas 1 39 | Número de columnas repetidas 2 40 | Columnas con más de la mitad de datos faltantes 4 41 | Columnas con más del 10% de datos como extremos 0 42 | Uso de memoria del conjunto de datos en MB (aprox) 12 43 | dtype: int32 44 | 45 | 46 | Tipos de cada columna 47 | --------------------- 48 | 49 | El método :py:meth:`CalidadDatos.TipoColumnas` calcula el tipo de cada columna de tres maneras diferentes. 50 | 51 | La primera es el tipo general de la columna en español. Indica si el tipo es numérico, texto, fecha, booleano u otro. 52 | 53 | La segunda muestra el tipo general según el método dtypes de Python. 54 | 55 | La tercera manera muestra los tipos de cada celda de cada columna. Es decir, muestra la distribución de tipos de cada columna. El tipo que más aparece en esa columna se muestra en la variable 'tipo_especifico_1' de la tabla de tipos y muestra el porcentaje. En caso de haber más de un tipo, se mostrará en las siguientes columnas 'tipo_especifico_#' 56 | 57 | El ejemplo abajo muestra cómo el es código para generar los resultados de los tipos con el método 'TipoCOlumnas'. Los parámetros del método especifican qué tipo se quiere mostrar para las columnas (con las opciones True o False) 58 | 59 | 60 | .. code-block:: python 61 | 62 | >>> tipos = datos_covid.TipoColumnas(tipoGeneral=True, 63 | tipoGeneralPython=True, 64 | tipoEspecifico=True) 65 | >>> tipos 66 | 67 | 68 | =========================== ============ =================== ================================================= ================================================= 69 | index tipo_general tipo_general_python tipo_especifico_1 tipo_especifico_2 70 | =========================== ============ =================== ================================================= ================================================= 71 | ID de caso Texto string 'str': 100.0% 72 | Fecha de notificación Fecha datetime64[ns] 'pandas._libs.tslibs.timestamps.Timestamp': 10... 73 | Código DIVIPOLA Texto string 'str': 100.0% 74 | Ciudad de ubicación Texto string 'str': 100.0% 75 | Departamento o Distrito Texto string 'str': 100.0% 76 | Atención Texto string 'str': 99.71% 'pandas._libs.missing.NAType': 0.29% 77 | Edad Numérico Int64 'int': 100.0% 78 | Edad 2 Numérico Int64 'int': 100.0% 79 | Edad meses Numérico Int64 'int': 100.0% 80 | Sexo Texto string 'str': 100.0% 81 | Tipo Texto string 'str': 100.0% 82 | Estado Texto string 'str': 99.66% 'pandas._libs.missing.NAType': 0.34% 83 | País de procedencia Texto string 'pandas._libs.missing.NAType': 98.58% 'str': 1.42% 84 | Fecha de inicio de síntomas Texto string 'str': 100.0% 85 | Fecha de muerte Fecha datetime64[ns] 'pandas._libs.tslibs.nattype.NaTType': 95.38% 'pandas._libs.tslibs.timestamps.Timestamp': 4.62% 86 | Fecha diagnostico Fecha datetime64[ns] 'pandas._libs.tslibs.timestamps.Timestamp': 98... 'pandas._libs.tslibs.nattype.NaTType': 1.59% 87 | Fecha recuperado Fecha datetime64[ns] 'pandas._libs.tslibs.timestamps.Timestamp': 91... 'pandas._libs.tslibs.nattype.NaTType': 8.67% 88 | Fecha reporte web Fecha datetime64[ns] 'pandas._libs.tslibs.timestamps.Timestamp': 10... 89 | Fecha de registro Fecha datetime64[ns] 'pandas._libs.tslibs.timestamps.Timestamp': 10... 90 | Tipo recuperación Texto string 'str': 91.33% 'pandas._libs.missing.NAType': 8.67% 91 | Codigo departamento Texto string 'str': 100.0% 92 | Codigo pais Texto string 'pandas._libs.missing.NAType': 98.65% 'str': 1.35% 93 | Pertenencia etnica Texto string 'str': 98.13% 'pandas._libs.missing.NAType': 1.87% 94 | Nombre grupo etnico Texto string 'pandas._libs.missing.NAType': 97.97% 'str': 2.03% 95 | Diccionario Texto string 'str': 100.0% 96 | =========================== ============ =================== ================================================= ================================================= 97 | 98 | 99 | Datos faltantes 100 | --------------- 101 | 102 | El método :py:meth:`CalidadDatos.ValoresFaltantes` permite calcular el número o porcentaje de valores faltantes de un conjunto de datos. Si el parámetro 'numero' tiene asignado el valor True, se calcula el número de valores faltantes de cada columna. De lo contrario, si es False, se calcula el porcentaje. 103 | 104 | El ejemplo a continuación presenta los porcentajes de datos faltantes de cada columna del conjunto de datos de COVID-19 105 | 106 | 107 | .. code-block:: python 108 | 109 | >>> faltantes = datos_covid.ValoresFaltantes(numero = False) 110 | >>> faltantes 111 | 112 | ID de caso 0.000000 113 | Fecha de notificación 0.000000 114 | Código DIVIPOLA 0.000000 115 | Ciudad de ubicación 0.000000 116 | Departamento o Distrito 0.000000 117 | Atención 0.002941 118 | Edad 0.000000 119 | Edad 2 0.000000 120 | Edad meses 0.000000 121 | Sexo 0.000000 122 | Tipo 0.000000 123 | Estado 0.003414 124 | País de procedencia 0.985766 125 | Fecha de inicio de síntomas 0.000000 126 | Fecha de muerte 0.953837 127 | Fecha diagnostico 0.015941 128 | Fecha recuperado 0.086701 129 | Fecha reporte web 0.000000 130 | Fecha de registro 0.000000 131 | Tipo recuperación 0.086701 132 | Codigo departamento 0.000000 133 | Codigo pais 0.986512 134 | Pertenencia etnica 0.018745 135 | Nombre grupo etnico 0.979685 136 | Diccionario 0.000000 137 | dtype: float64 138 | 139 | 140 | Datos duplicados 141 | ---------------- 142 | 143 | El método :py:meth:`CalidadDatos.CantidadDuplicados` calcula el número o porcentaje de duplicados en el conjunto de datos. 144 | 145 | El ejemplo abajo calcula el número de duplicados para filas y columnas del conjunto de datos de COVID-19. 146 | 147 | .. code-block:: python 148 | 149 | >>> # Número de filas duplicadas. 150 | >>> # Se escribe el parámetro eje = 0, para especificar fila 151 | >>> # Se escribe el parámetro numero = True, para especificar el número de duplicados (si es False se calcula el porcentaje) 152 | >>> filas_duplicadas = datos_covid.CantidadDuplicados(eje = 0, numero = True) 153 | 154 | >>> # Número de columnas duplicadas. 155 | >>> # Se escribe el parámetro eje = 1, para especificar columna 156 | >>> # Se escribe el parámetro numero = False, para especificar el porcentaje de duplicados 157 | >>> columnas_duplicadas = datos_covid.CantidadDuplicados(eje = 1, numero = True) 158 | 159 | >>> print("Filas duplicadas: ", filas_duplicadas) 160 | >>> print("Columnas duplicadas: ", columnas_duplicadas) 161 | 162 | Filas duplicadas: 1 163 | Columnas duplicadas: 2 164 | 165 | 166 | 167 | Emparejamiento de duplicados 168 | ---------------------------- 169 | 170 | El método :py:meth:`CalidadDatos.EmparejamientoDuplicados` permite mostrar los nombres de filas o columnas que son exactamente iguales. El parámetro 'col' especifica si se quieren emparejar los duplicados de filas al asignarlo a False. Para emparejar las columnas se escribe True. 171 | 172 | EL ejemplo abajo muestra los nombres de las filas duplicadas en cada columna de la tabla. Por ejemplo, la columna de la tabla 'Filas iguales 1' muestra que las filas 1 y 2 son duplicadas. 173 | 174 | .. code-block:: python 175 | 176 | >>> emparejamiento_dupli_filas = datos_covid.EmparejamientoDuplicados(col = False) 177 | >>> emparejamiento_dupli_filas 178 | 179 | ===== =============== 180 | index Filas iguales 1 181 | ===== =============== 182 | 0 267 183 | 1 269 184 | ===== =============== 185 | 186 | 187 | EL ejemplo abajo muestra los nombres de las columnas duplicadas en cada columna de la tabla. Por ejemplo, la columna de la tabla 'Columnas iguales 1' muestra que las columnas 'Edad' y 'Edad 2' son duplicadas. 188 | 189 | .. code-block:: python 190 | 191 | >>> emparejamiento_dupli_cols = datos_covid.EmparejamientoDuplicados(col = True) 192 | >>> emparejamiento_dupli_cols 193 | 194 | ===== ================== ================== 195 | index Columnas iguales 1 Columnas iguales 2 196 | ===== ================== ================== 197 | 0 Edad Fecha reporte web 198 | 1 Edad 2 Fecha de registro 199 | ===== ================== ================== 200 | 201 | 202 | Estadísticas descriptivas de variables numéricas 203 | ------------------------------------------------ 204 | 205 | El método :py:meth:`CalidadDatos.DescripcionNumericas` permite calcular estadísticas descriptivas para variables numéricas tales como el promedio, la desviación estándar, el mínimo, máximo, mediana (percentil 50), valores faltantes y extremos. 206 | 207 | El objetivo de estos cálculos es verificar si las variables del conjunto de datos contienen los valores esperados o si existen errores en la digitación de los valores 208 | 209 | El ejemplo abajo muestra las estadísticas descriptivas para las variables 'Edad', 'Edad_2' y 'Edad meses' 210 | 211 | .. code-block:: python 212 | 213 | >>> descr_numericas = datos_covid.DescripcionNumericas() 214 | >>> descr_numericas 215 | 216 | ========== ======= ========== ========== === ===== ===== ===== ====== ======= ============== ============== ============== 217 | index count mean std min 25% 50% 75% max missing outliers_total outliers_altos outliers_bajos 218 | ========== ======= ========== ========== === ===== ===== ===== ====== ======= ============== ============== ============== 219 | Edad 65616.0 39.175536 18.661339 0.0 26.0 36.0 52.0 104.0 0.0 0.002865 0.002865 0.0 220 | Edad 2 65616.0 39.175536 18.661339 0.0 26.0 36.0 52.0 104.0 0.0 0.002865 0.002865 0.0 221 | Edad meses 65616.0 476.099625 223.962309 1.0 318.0 443.0 626.0 1250.0 0.0 0.004054 0.004054 0.0 222 | ========== ======= ========== ========== === ===== ===== ===== ====== ======= ============== ============== ============== 223 | 224 | Es posible calcular las estadísticas descriptivas para algunas variables únicamente. Esto se hace al asignar una lista con las variables de interés al parámetro 'variables', como se muestra a continuación 225 | 226 | .. code-block:: python 227 | 228 | >>> descr_numericas = datos_covid.DescripcionNumericas(variables = ["Edad", "Edad meses"]) 229 | >>> descr_numericas 230 | 231 | ========== ======= ========== ========== === ===== ===== ===== ====== ======= ============== ============== ============== 232 | index count mean std min 25% 50% 75% max missing outliers_total outliers_altos outliers_bajos 233 | ========== ======= ========== ========== === ===== ===== ===== ====== ======= ============== ============== ============== 234 | Edad 65616.0 39.175536 18.661339 0.0 26.0 36.0 52.0 104.0 0.0 0.002865 0.002865 0.0 235 | Edad meses 65616.0 476.099625 223.962309 1.0 318.0 443.0 626.0 1250.0 0.0 0.004054 0.004054 0.0 236 | ========== ======= ========== ========== === ===== ===== ===== ====== ======= ============== ============== ============== 237 | 238 | 239 | Estadísticas descriptivas de variables categóricas 240 | -------------------------------------------------- 241 | 242 | El método :py:meth:`CalidadDatos.DescripcionCategoricas` calcula la frecuencia, tanto en número como en porcentaje del total de filas, de los valores de las variables que se consideran numéricas. 243 | 244 | Las variables se consideran categóricas si contienen valores limitados. Por defecto, el máximo número de categorías es 30 y las categorías no pueden representar más del 50% del total de filas de la columna. Estos valores se pueden modificar en los parámetros 'limite' y 'categoriasMaximas' del método 'DescripcionCategoricas'. 245 | 246 | Es posible también especificar si las variables numéricas con pocos valores se quieren incluir en el análisis. Por ejemplo, variables que contienen únicamente los números 1 y 2. Para agregar las variables al análisis, se asigna el valor True al parámetro incluirNumericas (el cual está por defecto) y False si no se desean incluir. 247 | 248 | Por último, es posible agregar una lista limitada de variables al análisis, asignando una lista de Python con las variables al parámetro 'variables' 249 | 250 | El ejemplo abajo muestra cómo se calculan las frecuencias de categorías de variables categóricas con los parámetros del método DescripcionCategoricas por defecto 251 | 252 | 253 | .. code-block:: python 254 | 255 | >>> descr_categoricas = datos_covid.DescripcionCategoricas(limite=0.5, 256 | >>> categoriasMaximas=30, 257 | >>> incluirNumericos=True, 258 | >>> variables=None) 259 | >>> descr_categoricas 260 | 261 | ===== ================== ================================ ========== ============================= 262 | index Columna Valor Frecuencia Porcentaje del total de filas 263 | ===== ================== ================================ ========== ============================= 264 | 0 Atención Recuperado 59927.0 0.913299 265 | 1 Atención Fallecido 2914.0 0.044410 266 | 2 Atención Hospital 2138.0 0.032584 267 | 3 Atención Hospital UCI 438.0 0.006675 268 | 4 Atención Casa 6.0 0.000091 269 | 5 Atención Datos faltantes 193.0 0.002941 270 | 6 Atención Total categorías (incluye NA): 6 NaN NaN 271 | 0 Sexo M 35552.0 0.541819 272 | 1 Sexo F 30056.0 0.458059 273 | 2 Sexo f 6.0 0.000091 274 | 3 Sexo m 2.0 0.000030 275 | 4 Sexo Datos faltantes 0.0 0.000000 276 | 5 Sexo Total categorías (incluye NA): 4 NaN NaN 277 | 0 Tipo En estudio 50836.0 0.774750 278 | 1 Tipo Relacionado 13847.0 0.211031 279 | 2 Tipo Importado 933.0 0.014219 280 | 3 Tipo Datos faltantes 0.0 0.000000 281 | 4 Tipo Total categorías (incluye NA): 3 NaN NaN 282 | 0 Estado Leve 52084.0 0.793770 283 | 1 Estado Asintomático 6811.0 0.103801 284 | 2 Estado Moderado 3135.0 0.047778 285 | 3 Estado Fallecido 2914.0 0.044410 286 | 4 Estado Grave 448.0 0.006828 287 | 5 Estado Datos faltantes 224.0 0.003414 288 | 6 Estado Total categorías (incluye NA): 6 NaN NaN 289 | 0 Tipo recuperación PCR 35370.0 0.539045 290 | 1 Tipo recuperación Tiempo 24557.0 0.374253 291 | 2 Tipo recuperación Datos faltantes 5689.0 0.086701 292 | 3 Tipo recuperación Total categorías (incluye NA): 3 NaN NaN 293 | 0 Pertenencia etnica Otro 57670.0 0.878901 294 | 1 Pertenencia etnica Negro 5003.0 0.076247 295 | 2 Pertenencia etnica Indígena 1333.0 0.020315 296 | 3 Pertenencia etnica Rom 293.0 0.004465 297 | 4 Pertenencia etnica Raizal 72.0 0.001097 298 | 5 Pertenencia etnica Palenquero 15.0 0.000229 299 | 6 Pertenencia etnica Datos faltantes 1230.0 0.018745 300 | 7 Pertenencia etnica Total categorías (incluye NA): 7 NaN NaN 301 | 0 Diccionario {1} 32808.0 0.500000 302 | 1 Diccionario {2} 32808.0 0.500000 303 | 2 Diccionario Datos faltantes 0.0 0.000000 304 | 3 Diccionario Total categorías (incluye NA): 2 NaN NaN 305 | ===== ================== ================================ ========== ============================= 306 | 307 | 308 | Peso de las variables en la memoria RAM 309 | --------------------------------------- 310 | 311 | Para calcular cuál es el peso de cada variable, se utiliza el método :py:meth:`CalidadDatos.Memoria`, como se muestra en el ejemplo abajo. El parámetro 'unidad' indica que se quiere calcular en Mega Bytes ('Mb') y el parámetro 'col' indica que se calcula para cada variable. En caso de desear calcular el peso total del conjunto de datos, se asigna False al parámetro 'col'. 312 | 313 | .. code-block:: python 314 | 315 | >>> peso_memoria = datos_covid.Memoria(col=True, unidad="Mb") 316 | >>> peso_memoria 317 | 318 | Index 0.000122 319 | ID de caso 0.500610 320 | Fecha de notificación 0.500610 321 | Código DIVIPOLA 0.500610 322 | Ciudad de ubicación 0.500610 323 | Departamento o Distrito 0.500610 324 | Atención 0.500610 325 | Edad 0.563187 326 | Edad 2 0.563187 327 | Edad meses 0.563187 328 | Sexo 0.500610 329 | Tipo 0.500610 330 | Estado 0.500610 331 | País de procedencia 0.500610 332 | Fecha de inicio de síntomas 0.500610 333 | Fecha de muerte 0.500610 334 | Fecha diagnostico 0.500610 335 | Fecha recuperado 0.500610 336 | Fecha reporte web 0.500610 337 | Fecha de registro 0.500610 338 | Tipo recuperación 0.500610 339 | Codigo departamento 0.500610 340 | Codigo pais 0.500610 341 | Pertenencia etnica 0.500610 342 | Nombre grupo etnico 0.500610 343 | Diccionario 0.500610 344 | dtype: float64 345 | 346 | 347 | Correlación entre variables numéricas 348 | ------------------------------------- 349 | 350 | El método :py:meth:`CalidadDatos.CorrelacionNumericas` calcula una matriz de correlación entre las variables numéricas del conjunto de datos. El parámetro 'metodo' especifica si se desea calcular las correlaciones con el método Pearson ('pearson'), Kendall ('kendall') o Spearman ('spearman'). 351 | 352 | El siguiente ejemplo presenta la matriz de correlación para variables numéricas del conjunto de datos de COVID-19. 353 | 354 | .. code-block:: python 355 | 356 | >>> corr_numericas = datos_covid.CorrelacionNumericas(metodo="pearson", variables=None) 357 | >>> corr_numericas 358 | 359 | ========== ====== ====== ========== 360 | index Edad Edad 2 Edad meses 361 | ========== ====== ====== ========== 362 | Edad 1.0000 1.0000 0.9999 363 | Edad 2 1.0000 1.0000 0.9999 364 | Edad meses 0.9999 0.9999 1.0000 365 | ========== ====== ====== ========== 366 | 367 | 368 | Correlación de variables categóricas 369 | ------------------------------------ 370 | 371 | El método :py:meth:`CalidadDatos.CorrelacionCategoricas` calcula una matriz de correlación para variables categóricas. Contiene los mismos parámetros que se explicaron en la Sección 'Estadísticas descriptivas de variables categóricas', para definir variables categóricas, pero incluye también el parámetro 'metodo'. Este especifica si se quiere calcular la matriz con el método Cramer ('cramer') o con la metodología Phik ('phik'), de la librería Phik de Python. 372 | 373 | A continuación se calcula la matriz de correlación de variables categóricas para el conjunto de datos de COVID-19 374 | 375 | .. code-block:: python 376 | 377 | >>> corr_categoricas = datos_covid.CorrelacionCategoricas(metodo="phik") 378 | >>> corr_categoricas 379 | 380 | ====================== ======== ======== ======== ======== ================= ================== =========== 381 | index Atención Sexo Tipo Estado Tipo recuperación Pertenencia etnica Diccionario 382 | ====================== ======== ======== ======== ======== ================= ================== =========== 383 | Atención 1.000000 0.038193 0.195794 0.987038 0.941437 0.028540 0.000000 384 | Sexo 0.038193 1.000000 0.094794 0.041878 0.025933 0.000000 0.000000 385 | Tipo 0.195794 0.094794 1.000000 0.325888 0.320547 0.133658 0.000000 386 | Estado 0.987038 0.041878 0.325888 1.000000 0.917328 0.067380 0.004040 387 | Tipo recuperación 0.941437 0.025933 0.320547 0.917328 1.000000 0.051298 0.000000 388 | Pertenencia etnica 0.028540 0.000000 0.133658 0.067380 0.051298 1.000000 0.002036 389 | Diccionario 0.000000 0.000000 0.000000 0.004040 0.000000 0.002036 1.000000 390 | ====================== ======== ======== ======== ======== ================= ================== =========== 391 | 392 | -------------------------------------------------------------------------------- /leila/reporte.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os, re 4 | import datetime 5 | import pandas as pd 6 | from jinja2 import Environment, PackageLoader 7 | 8 | ##### Quitar luego 9 | import sys 10 | sys.path.insert(0, "leila") 11 | ##### 12 | 13 | from leila.calidad_datos import CalidadDatos 14 | from leila.datos_gov import DatosGov 15 | 16 | def df_as_html(base, id=None, classes=None): 17 | """ Transforma el dataframe de entrada en una tabla HTML, se asignan al tab table las clases 'table' y 18 | 'table-condensed' utilizadas por `Bootstrap v3.4`_. 19 | 20 | .. _Bootstrap v3.4: https://getbootstrap.com/docs/3.4/ 21 | 22 | :param base: (dataframe) dataframe de interés a ser transformado en tabla. 23 | :param id: (str) id que se le desea asignar a la tabla. 24 | :param classes: (list) lista de strings de las clases que se desean agregar a la tabla. 25 | :return: código de la tabla en formato HTML con los datos del dataframe. 26 | """ 27 | # html = base.to_html(table_id='mi_tabla', index=False, classes=['table', 'table-condensed', 'table-hover']) \ 28 | 29 | my_classes = ['table', 'table-condensed'] 30 | if classes is not None: 31 | my_classes.extend(classes) 32 | 33 | html = base.to_html(index=False, table_id=id, classes=my_classes) \ 34 | .replace('table border="1" class="dataframe ', 'table class="') 35 | return html 36 | 37 | 38 | def generar_reporte(datos=None, titulo='Reporte perfilamiento', archivo='perfilamiento_leila.html', 39 | secciones = {'generales':True, 'muestra_datos': True, 'correlaciones': True, 40 | 'especificas': ['tipo', 'frecuencias', 'duplicados_columnas', 'descriptivas']}, **kwargs): 41 | """ 42 | Genera un reporte de calidad de datos en formato HTML. :ref:`Ver ejemplo ` 43 | 44 | :param datos: (str, pandas.DataFrame, leila.CalidadDatos) Se acepta cualquier ruta o path a archivos tipo `.xlsx` \ 45 | o `.csv` (recomendado). Si desea pasar un `DataFrame` de pandas, LEILA soporta este tipo \ 46 | de entrada. LEILA también soporta como entrada objectos del tipo \ 47 | `leila.CalidadDatos`. También se acepta la identificación de la base de datos asociado \ 48 | con la API de Socrata (de Datos Abiertos). 49 | :param titulo: (str) valor por defecto: 'Reporte perfilamiento'. Título del reporte a generar. 50 | :param archivo: (str) valor por defecto: 'perfilamiento.html'. Ruta donde guardar el reporte. 51 | :param secciones: (dic) Diccionario indicando que secciones incluir en el reporte. :ref:`Ver ejemplo ` |br| Las opciones son las siguientes: \ 52 | |ul| 53 | |li| 'generales': (bool) {True, False}. Valor por defecto: True. Indica si desea incluir la sección de 'Estadísticas generales' en el reporte. |/li| 54 | |li| 'muestra_datos': (bool) {True, False}. Valor por defecto: True. Indica si desea incluir la sección 'Muestra de datos' en el reporte. |/li| 55 | |li| 'correlaciones': (bool/list) {True, False, Lista}. Valor por defecto: True. Puede tomar un valor booleano indicando \ 56 | si desea incluir la sección de 'Correlaciones' en el reporte y todas sus pestañas. O mediante una lista de strings indicar \ 57 | que pestaña de la sección incluir. Valores posibles: 'pearson', 'kendall', 'spearman', 'cramer', 'phik' |/li| 58 | |li| 'especificas': (bool/list) {True, False, Lista}. Valor por defecto: ['tipo', 'frecuencias', 'duplicados_columnas', 'descriptivas']. \ 59 | Puede tomar un valor booleano indicando si desea incluir la sección de 'Estadísticas específicas' en el reporte y todas sus pestañas. \ 60 | O mediante una lista de strings indicar que pestaña de la sección incluir. Valores posibles: 'tipo', 'frecuencias', \ 61 | 'duplicados', 'duplicados_filas', 'duplicados_columnas', 'descriptivas' |/li| 62 | |/ul| 63 | """ 64 | 65 | link_datos_abiertos = None 66 | html_descr_col_meta = None 67 | html_metadatos_full = None 68 | html_metadatos_head = None 69 | html_metadatos_tail = None 70 | 71 | if isinstance(datos, str): 72 | if datos == '': 73 | raise ValueError( 74 | "El parámetro datos no puede ser vacío" 75 | ) 76 | 77 | elif re.match("[A-Za-z0-9]{4}-[A-Za-z0-9]{4}", datos): 78 | # FIXME: BORRAR **kwargs 79 | api_id = datos 80 | datos = DatosGov().cargar_base(api_id=datos, **kwargs) 81 | 82 | base = CalidadDatos(datos) 83 | df_metadatos = pd.DataFrame.from_dict(datos.metadatos(), orient='index') 84 | 85 | desc_col = pd.DataFrame.from_dict(df_metadatos.loc['columnas', 0], orient='index') 86 | desc_col = desc_col.reset_index() 87 | desc_col = desc_col.rename(columns={"index": "Variable", "tipo": "Tipo", "descripcion":"Descripción", "nombre_df":"Nombre variable"}) 88 | desc_col = desc_col[['Variable', 'Nombre variable', 'Tipo', 'Descripción']] 89 | 90 | df_metadatos = df_metadatos.drop("columnas") 91 | 92 | df_metadatos.loc['numero_vistas', 0] = str('{:,.0f}'.format(df_metadatos.loc['numero_vistas', 0])) 93 | df_metadatos.loc['numero_descargas', 0] = str('{:,.0f}'.format(df_metadatos.loc['numero_descargas', 0])) 94 | 95 | if df_metadatos.loc['numero_filas', 0] != 'NA': 96 | df_metadatos.loc['numero_filas', 0] = str('{:,.0f}'.format( df_metadatos.loc['numero_filas', 0])) 97 | 98 | if df_metadatos.loc['numero_columnas', 0] != 'NA': 99 | df_metadatos.loc['numero_columnas', 0] = str('{:,.0f}'.format(df_metadatos.loc['numero_columnas', 0])) 100 | 101 | df_metadatos = df_metadatos.T 102 | df_metadatos = df_metadatos.rename( 103 | columns={ 104 | "numero_api": "Número API", 105 | "nombre": "Nombre", 106 | "descripcion":"Descripción", 107 | "tipo":"Tipo", 108 | "url":"URL", 109 | "categoria":"Categoría", 110 | "fecha_creacion":"Fecha de creación", 111 | "numero_vistas":"Número de vistas", 112 | "numero_descargas":"Número de descargas", 113 | "licencia":"Licencia", 114 | "fecha_publicacion":"Fecha de publicación", 115 | "base_publica":"Base pública", 116 | "fecha_actualizacion":"Fecha de actualización", 117 | "numero_filas":"Número de filas", 118 | "numero_columnas":"Número de columnas", 119 | "licencia_url":"Licencia URL", 120 | "entidad":"Entidad", 121 | "entidad_municipio":"Entidad municipio", 122 | "entidad_sector":"Entidad sector", 123 | "entidad_departamento":"Entidad departamento", 124 | "entidad_orden":"Entidad orden", 125 | "entidad_dependencia":"Entidad dependencia", 126 | "cobertura":"Cobertura", 127 | "idioma":"Idioma", 128 | "frecuencia_actualizacion":"Frecuencia de actualización", 129 | "dueno":"Dueño", 130 | }) 131 | df_metadatos = df_metadatos.T 132 | 133 | df_metadatos = df_metadatos.reset_index() 134 | df_metadatos.columns = ['Atributo', 'Valor'] 135 | 136 | # link_datos_abiertos = df_metadatos[df_metadatos['Atributo'] == 'URL']['Valor'].item() 137 | link_datos_abiertos = f'https://www.datos.gov.co/resource/{api_id}' 138 | 139 | df_metadatos.replace('\n', '@#$', regex=True, inplace=True) 140 | 141 | html_descr_col_meta = df_as_html( 142 | desc_col, classes=['white_spaces']) 143 | 144 | html_metadatos_full = df_as_html( 145 | df_metadatos, classes=['white_spaces']) 146 | 147 | html_metadatos_head = df_as_html( 148 | df_metadatos[:3], classes=['white_spaces']) 149 | 150 | html_metadatos_tail = df_as_html( 151 | df_metadatos[-(len(datos.metadatos().keys()) - 4):], classes=['white_spaces']) 152 | 153 | html_metadatos_full = html_metadatos_full.replace('@#$', '
    ') 154 | html_metadatos_head = html_metadatos_head.replace('@#$', '
    ') 155 | html_metadatos_tail = html_metadatos_tail.replace('@#$', '
    ') 156 | print('--------------------------------------------------------------------------------------------') 157 | 158 | else: 159 | base = CalidadDatos(datos) 160 | 161 | elif (datos.__class__.__name__ == 'CalidadDatos'): 162 | base = datos 163 | 164 | else: 165 | base = CalidadDatos(datos) 166 | 167 | timestamp = datetime.datetime.now() 168 | current_time = timestamp.strftime("%d-%m-%Y %I:%M:%S %p") 169 | 170 | # ------------------------------------------------------------------------ 171 | # Estadísticas generales ------------------------------------------------- 172 | if secciones.get('generales')==True: 173 | dataframe_summary = base.Resumen().to_frame().reset_index() 174 | dataframe_summary.columns = ['Categoría', 'Valor'] 175 | 176 | try: 177 | dataframe_summary['Valor'] = dataframe_summary['Valor'].apply( 178 | '{:,.0f}'.format) 179 | except BaseException: 180 | pass 181 | 182 | html_data_summary_full = df_as_html(dataframe_summary) 183 | html_data_summary_head = df_as_html(dataframe_summary[:6]) 184 | html_data_summary_tail = df_as_html(dataframe_summary[-6:]) 185 | else: 186 | html_data_summary_full=None 187 | html_data_summary_head=None 188 | html_data_summary_tail=None 189 | 190 | # ------------------------------------------------------------------------ 191 | # Muestra de datos ------------------------------------------------------- 192 | if secciones.get('muestra_datos')==True: 193 | # Head 194 | html_dataframe_head = df_as_html(base.base.head(10)) 195 | # Tail 196 | html_dataframe_tail = df_as_html(base.base.tail(10)) 197 | # Shape 198 | df_shape = base.base.shape 199 | dataframe_shape = str('{:,.0f}'.format( 200 | df_shape[0])) + ' filas x ' + str('{:,.0f}'.format(df_shape[1])) + ' columnas' 201 | else: 202 | html_dataframe_head = None 203 | html_dataframe_tail = None 204 | dataframe_shape = None 205 | 206 | # ------------------------------------------------------------------------ 207 | # Estadísticas específicas 208 | s_especificas=secciones.get('especificas') 209 | seccion_especificas=False 210 | especificas_active=None 211 | 212 | # ------------------------------------------------------------------------ 213 | if (isinstance(s_especificas, list) and 'tipo' in s_especificas) or (s_especificas==True): 214 | especificas_tipo=True 215 | seccion_especificas=True 216 | if especificas_active is None: especificas_active='tipo' 217 | 218 | # Tab 5 - Tipo de las columnas ------------------------------------------- 219 | tipo_columnas_df = base.TipoColumnas() 220 | 221 | df_headers = list(tipo_columnas_df) 222 | df_headers = [w.replace('tipo_general', 'Tipo general') 223 | .replace('_python', ' (Python)') 224 | .replace('tipo_especifico_', 'Tipo especifico ') for w in df_headers] 225 | tipo_columnas_df.columns = df_headers 226 | 227 | header_list_2 = list(tipo_columnas_df) 228 | variables_list_2 = list(tipo_columnas_df.T) 229 | 230 | tipo_columnas_df = tipo_columnas_df.reset_index() 231 | items_2 = tipo_columnas_df.values.tolist() 232 | 233 | else: 234 | especificas_tipo=False 235 | header_list_2=None 236 | variables_list_2=None 237 | items_2=None 238 | 239 | # ------------------------------------------------------------------------ 240 | if (isinstance(s_especificas, list) and 'frecuencias' in s_especificas) or (s_especificas==True): 241 | 242 | especificas_frecuencias=True 243 | seccion_especificas=True 244 | if especificas_active is None: especificas_active='frecuencias' 245 | 246 | # Tab 3 - Frecuencia de categorías --------------------------------------- 247 | dataframe_unique_text = base.DescripcionCategoricas() 248 | try: 249 | dataframe_unique_text['Frecuencia'] = dataframe_unique_text['Frecuencia'].apply( 250 | '{:,.0f}'.format) 251 | except BaseException: 252 | pass 253 | 254 | try: 255 | dataframe_unique_text['Porcentaje del total de filas'] = dataframe_unique_text[ 256 | 'Porcentaje del total de filas'].apply(lambda x: str(format(x * 100, ',.2f')) + '%') 257 | except BaseException: 258 | pass 259 | 260 | try: 261 | variables_list_3 = dataframe_unique_text.Columna.unique() 262 | columnas_list_3 = list(dataframe_unique_text) 263 | items_3 = dataframe_unique_text.values.tolist() 264 | except BaseException: 265 | especificas_frecuencias=False 266 | variables_list_3=None 267 | columnas_list_3=None 268 | items_3=None 269 | pass 270 | else: 271 | especificas_frecuencias=False 272 | variables_list_3=None 273 | columnas_list_3=None 274 | items_3=None 275 | 276 | # ------------------------------------------------------------------------ 277 | # DONE: REVISAR - emparejamiento de filas dejarlo en FALSE por defecto 278 | # if (isinstance(s_especificas, list) and 'duplicados' in s_especificas) or (s_especificas==True): 279 | if (isinstance(s_especificas, list) and any(item in ['duplicados', 'duplicados_filas', 'duplicados_columnas'] for item in s_especificas)) or (s_especificas==True): 280 | 281 | mensaje_duplicados = '
    ' 282 | seccion_especificas=True 283 | if especificas_active is None: especificas_active='duplicados' 284 | 285 | # Tab 4 - Datos duplicados ----------------------------------------------- 286 | especificas_duplicados_filas=False 287 | especificas_duplicados_columnas=False 288 | html_dataframe_duplic_filas = None 289 | html_dataframe_duplic_colum = None 290 | 291 | if (isinstance(s_especificas, list) and any(item in ['duplicados', 'duplicados_filas'] for item in s_especificas)) or (s_especificas==True): 292 | especificas_duplicados_filas=True 293 | dataframe_duplic_filas = base.EmparejamientoDuplicados(col=False) 294 | 295 | if dataframe_duplic_filas is not None: 296 | filas_duplicadas = dataframe_duplic_filas.nunique().sum() 297 | filas_numero = base.base.shape[0] 298 | porcentaje_duplicados = (filas_duplicadas / filas_numero) 299 | mensaje_duplicados += f'Filas duplicadas {format(filas_duplicadas, ",.0f")} de {format(filas_numero, ",.0f")} ({str(format(porcentaje_duplicados * 100, ",.2f")) + "%"}). ' 300 | 301 | dataframe_duplic_filas.fillna('', inplace=True) 302 | html_dataframe_duplic_filas = df_as_html(dataframe_duplic_filas, classes=['highlight_column']) 303 | 304 | if (isinstance(s_especificas, list) and any(item in ['duplicados', 'duplicados_columnas'] for item in s_especificas)) or (s_especificas==True): 305 | especificas_duplicados_columnas=True 306 | dataframe_duplic_colum = base.EmparejamientoDuplicados(col=True) 307 | 308 | if dataframe_duplic_colum is not None: 309 | col_duplicadas = dataframe_duplic_colum.nunique().sum() 310 | col_numero = base.base.shape[1] 311 | porcentaje_duplicados = col_duplicadas / col_numero 312 | mensaje_duplicados += f'Columnas duplicadas {format(col_duplicadas, ",.0f")} de {format(col_numero, ",.0f")} ({str(format(porcentaje_duplicados * 100, ",.2f")) + "%"}). ' 313 | 314 | dataframe_duplic_colum.fillna('', inplace=True) 315 | html_dataframe_duplic_colum = df_as_html(dataframe_duplic_colum, classes=['highlight_column']) 316 | 317 | mensaje_duplicados += '' 318 | else: 319 | especificas_duplicados_filas=False 320 | especificas_duplicados_columnas=False 321 | html_dataframe_duplic_filas=None 322 | html_dataframe_duplic_colum=None 323 | mensaje_duplicados='' 324 | 325 | # ------------------------------------------------------------------------ 326 | if (isinstance(s_especificas, list) and 'descriptivas' in s_especificas) or (s_especificas==True): 327 | 328 | especificas_descriptivas=True 329 | seccion_especificas=True 330 | if especificas_active is None: especificas_active='descriptivas' 331 | 332 | # Tab 6 - Estadísticas descriptivas -------------------------------------- 333 | dataframe_descriptive_stats = base.DescripcionNumericas() 334 | 335 | header_list = None 336 | items = None 337 | variables_list = None 338 | if dataframe_descriptive_stats is not None: 339 | for col in ['freq', 'count', 'unique']: 340 | try: 341 | dataframe_descriptive_stats[col] = dataframe_descriptive_stats[ 342 | col].apply('{:,.0f}'.format) 343 | except BaseException: 344 | pass 345 | 346 | for col in ['mean', 'std', 'min', '25%', '50%', '75%', 'max']: 347 | try: 348 | dataframe_descriptive_stats[col] = dataframe_descriptive_stats[ 349 | col].apply('{:,.2f}'.format) 350 | except BaseException: 351 | pass 352 | 353 | for col in ['missing', 'outliers_total', 354 | 'outliers_altos', 'outliers_bajos']: 355 | try: 356 | dataframe_descriptive_stats[col] = dataframe_descriptive_stats[ 357 | col].apply(lambda x: str(format(x * 100, ',.2f')) + '%') 358 | except BaseException: 359 | pass 360 | 361 | df_headers = list(dataframe_descriptive_stats) 362 | df_headers = [w.replace('count', 'Conteo') 363 | .replace('unique', 'Valores únicos') 364 | .replace('mean', 'Media') 365 | .replace('std', 'Desviación estándar') 366 | .replace('min', 'Valor mín') 367 | .replace('max', 'Valor máx') 368 | .replace('missing', 'Faltantes') 369 | .replace('outliers_', 'Outliers ') 370 | .replace('top', 'Valor más común') 371 | .replace('freq', 'Frecuencia valor más común') for w in df_headers] 372 | dataframe_descriptive_stats.columns = df_headers 373 | 374 | header_list = list(dataframe_descriptive_stats) 375 | variables_list = list(dataframe_descriptive_stats.T) 376 | dataframe_descriptive_stats = dataframe_descriptive_stats.reset_index() 377 | items = dataframe_descriptive_stats.values.tolist() 378 | else: 379 | especificas_descriptivas=False 380 | header_list=None 381 | variables_list=None 382 | items=None 383 | 384 | # ------------------------------------------------------------------------ 385 | # Gráficos correlaciones ------------------------------------------------- 386 | s_correlaciones=secciones.get('correlaciones') 387 | seccion_correlaciones=False 388 | correlaciones_active=None 389 | 390 | # Escala de colores del heatmap 391 | heatmap_colorscale = [ 392 | ['0.000000000000', 'rgb(103, 0, 31)'], 393 | ['0.111111111111', 'rgb(178, 24, 43)'], 394 | ['0.222222222222', 'rgb(214, 96, 77)'], 395 | ['0.333333333333', 'rgb(244,165,130)'], 396 | ['0.444444444444', 'rgb(253,219,199)'], 397 | ['0.555555555556', 'rgb(209,229,240)'], 398 | ['0.666666666667', 'rgb(146,197,222)'], 399 | ['0.777777777778', 'rgb( 67,147,195)'], 400 | ['0.888888888889', 'rgb( 33,102,172)'], 401 | ['1.000000000000', 'rgb( 5, 48, 97)'] 402 | ] 403 | 404 | # Tab 1 - numérica - Pearson --------------------------------------------- 405 | if (isinstance(s_correlaciones, list) and 'pearson' in s_correlaciones) or (s_correlaciones==True): 406 | seccion_correlaciones=True 407 | if correlaciones_active==None: correlaciones_active='pearson' 408 | 409 | df_corre_pearson = base.CorrelacionNumericas(metodo="pearson") 410 | if df_corre_pearson is not None: 411 | corre_pearson_headers = list(df_corre_pearson) 412 | 413 | df_corre_pearson = df_corre_pearson.round(3).fillna('null') 414 | corre_pearson_values = df_corre_pearson.values.tolist() 415 | else: 416 | corre_pearson_headers=None 417 | corre_pearson_values=None 418 | else: 419 | corre_pearson_headers=None 420 | corre_pearson_values=None 421 | 422 | # Tab 2 - numérica - Kendall --------------------------------------------- 423 | if (isinstance(s_correlaciones, list) and 'kendall' in s_correlaciones) or (s_correlaciones==True): 424 | seccion_correlaciones=True 425 | if correlaciones_active==None: correlaciones_active='kendall' 426 | 427 | df_corre_kendall = base.CorrelacionNumericas(metodo="kendall") 428 | if df_corre_kendall is not None: 429 | corre_kendall_headers = list(df_corre_kendall) 430 | 431 | df_corre_kendall = df_corre_kendall.round(3).fillna('null') 432 | corre_kendall_values = df_corre_kendall.values.tolist() 433 | else: 434 | corre_kendall_headers=None 435 | corre_kendall_values=None 436 | else: 437 | corre_kendall_headers=None 438 | corre_kendall_values=None 439 | 440 | # Tab 3 - numérica - Pearson --------------------------------------------- 441 | if (isinstance(s_correlaciones, list) and 'spearman' in s_correlaciones) or (s_correlaciones==True): 442 | seccion_correlaciones=True 443 | if correlaciones_active==None: correlaciones_active='spearman' 444 | 445 | df_corre_spearman = base.CorrelacionNumericas(metodo="spearman") 446 | if df_corre_spearman is not None: 447 | corre_spearman_headers = list(df_corre_spearman) 448 | 449 | df_corre_spearman = df_corre_spearman.round(3).fillna('null') 450 | corre_spearman_values = df_corre_spearman.values.tolist() 451 | else: 452 | corre_spearman_headers=None 453 | corre_spearman_values=None 454 | else: 455 | corre_spearman_headers=None 456 | corre_spearman_values=None 457 | 458 | # Tab 4 - categórica - Cramer -------------------------------------------- 459 | if (isinstance(s_correlaciones, list) and 'cramer' in s_correlaciones) or (s_correlaciones==True): 460 | seccion_correlaciones=True 461 | if correlaciones_active==None: correlaciones_active='cramer' 462 | 463 | df_corre_cramer = base.CorrelacionCategoricas(metodo="cramer") 464 | corre_cramer_headers = list(df_corre_cramer) 465 | 466 | df_corre_cramer = df_corre_cramer.round(3).fillna('null') 467 | corre_cramer_values = df_corre_cramer.values.tolist() 468 | else: 469 | corre_cramer_headers=None 470 | corre_cramer_values=None 471 | 472 | # Tab 5 - categórica - Phik ---------------------------------------------- 473 | if (isinstance(s_correlaciones, list) and 'phik' in s_correlaciones) or (s_correlaciones==True): 474 | seccion_correlaciones=True 475 | if correlaciones_active==None: correlaciones_active='phik' 476 | 477 | df_corre_phik = base.CorrelacionCategoricas(metodo="phik") 478 | corre_phik_headers = list(df_corre_phik) 479 | 480 | df_corre_phik = df_corre_phik.round(3).fillna('null') 481 | corre_phik_values = df_corre_phik.values.tolist() 482 | else: 483 | corre_phik_headers=None 484 | corre_phik_values=None 485 | 486 | # ------------------------------------------------------------------------ 487 | # ------------------------------------------------------------------------ 488 | 489 | # Configuración inicial de Jinja 490 | env = Environment(loader=PackageLoader('leila')) 491 | 492 | # Carga el template a utilizar 493 | base_template = env.get_template('template.html') 494 | 495 | # Generación del reporte 496 | reporte_full_path = '' 497 | with open(archivo, "w", encoding='utf8') as HTML_file: 498 | output = base_template.render( 499 | title=titulo, 500 | current_time=current_time, 501 | link_datos_abiertos=link_datos_abiertos, 502 | html_descr_col_meta=html_descr_col_meta, 503 | html_metadatos_full=html_metadatos_full, 504 | html_metadatos_head=html_metadatos_head, 505 | html_metadatos_tail=html_metadatos_tail, 506 | html_data_summary_full=html_data_summary_full, 507 | html_data_summary_head=html_data_summary_head, 508 | html_data_summary_tail=html_data_summary_tail, 509 | header_list=header_list, 510 | variables_list=variables_list, 511 | items=items, 512 | header_list_2=header_list_2, 513 | variables_list_2=variables_list_2, 514 | items_2=items_2, 515 | html_dataframe_head=html_dataframe_head, 516 | html_dataframe_tail=html_dataframe_tail, 517 | dataframe_shape=dataframe_shape, 518 | variables_list_3=variables_list_3, 519 | columnas_list_3=columnas_list_3, 520 | items_3=items_3, 521 | html_dataframe_duplic_filas=html_dataframe_duplic_filas, 522 | html_dataframe_duplic_colum=html_dataframe_duplic_colum, 523 | generales=secciones.get('generales'), 524 | muestra_datos=secciones.get('muestra_datos'), 525 | seccion_especificas=seccion_especificas, 526 | especificas_active=especificas_active, 527 | especificas_tipo=especificas_tipo, 528 | especificas_frecuencias=especificas_frecuencias, 529 | especificas_duplicados_filas=especificas_duplicados_filas, 530 | especificas_duplicados_columnas=especificas_duplicados_columnas, 531 | mensaje_duplicados=mensaje_duplicados, 532 | especificas_descriptivas=especificas_descriptivas, 533 | seccion_correlaciones=seccion_correlaciones, 534 | correlaciones_active=correlaciones_active, 535 | heatmap_colorscale=heatmap_colorscale, 536 | corre_pearson_headers=corre_pearson_headers, 537 | corre_pearson_values=corre_pearson_values, 538 | corre_kendall_headers=corre_kendall_headers, 539 | corre_kendall_values=corre_kendall_values, 540 | corre_spearman_headers=corre_spearman_headers, 541 | corre_spearman_values=corre_spearman_values, 542 | corre_cramer_headers=corre_cramer_headers, 543 | corre_cramer_values=corre_cramer_values, 544 | corre_phik_headers=corre_phik_headers, 545 | corre_phik_values=corre_phik_values 546 | ) 547 | try: 548 | HTML_file.write(output) 549 | print( 550 | '--------------------------------------------------------------------------------------------') 551 | 552 | if archivo == 'perfilamiento_leila.html': 553 | if os.name == 'nt': 554 | reporte_full_path = os.getcwd() + "\\" + archivo 555 | else: 556 | import pathlib 557 | reporte_full_path = str( 558 | pathlib.Path().absolute()) + '/' + archivo 559 | else: 560 | reporte_full_path = archivo 561 | 562 | print(f'Se ha generado el reporte "{reporte_full_path}"') 563 | t1 = timestamp.strftime("%I:%M:%S %p") 564 | t2 = datetime.datetime.now() 565 | tiempo = str(t2 - timestamp).split(":") 566 | print(f"{t1} ({tiempo[1]} min {int(float(tiempo[2]))} seg)") 567 | 568 | except ValueError: 569 | print("Se presentó un error guardando el reporte HTML") 570 | 571 | try: 572 | print('--------------------------------------------------------------------------------------------') 573 | if os.name == 'nt': 574 | os.system(f'{reporte_full_path}') 575 | except FileNotFoundError: 576 | print("No se encontró el archivo reporte para abrir") 577 | -------------------------------------------------------------------------------- /sphinx/source/ejemplos/ejemplos_datos_gov.rst: -------------------------------------------------------------------------------- 1 | Ejemplos - Datos gov 2 | ==================== 3 | 4 | Ejemplo tabla_inventario 5 | ------------------------ 6 | 7 | 8 | .. code-block:: python 9 | 10 | >>> # Se importar la clase DatosGov del módulo datos_gov 11 | >>> from leila.datos_gov import DatosGov 12 | 13 | 14 | Se importa la tabla de inventario de datos.gov.co. Esta tabla contiene todas las publicaciones del Portal (conjuntos de datos, enlaces externos, mapas, gráficos, etc.). Ver documentación :py:meth:`DatosGov.tabla_inventario` 15 | 16 | .. code-block:: python 17 | 18 | >>> inventario = DatosGov().tabla_inventario() 19 | 20 | 21 | Las columnas de la tabla de inventario son las siguientes: 22 | 23 | ============================== ============== 24 | Columna Descripción 25 | ============================== ============== 26 | **numero_api** número API del conjunto de datos. Este es un carácter único de cada conjunto de datos del Portal que se usa como insumo para abrirlo desde código. 27 | **nombre** nombre de la publicación 28 | **descripcion** descripción de la publicación 29 | **dueno** dueño de la publicación. 30 | **base_publica** indica con un 'si' si la información del conjunto de datos es público y con un 'no' de lo contrario 31 | **tipo** indica el tipo de la publicación, que puede ser uno de los siguientes: 'conjunto de datos', 'enlace externo', 'mapa', 'grafico', 'vista filtrada', 'archivo o documento', 'historia', 'visualizacion', 'lente de datos', 'formulario', 'calendario'. 32 | **categoria** tema general del que trata la información publicada 33 | **terminos_clave** términos clave relacionados con la publicación 34 | **url** enlace web de la publicación en el Portal de Datos Abiertos 35 | **fecha_creacion** fecha de creación de la publicación 36 | **fecha_actualizacion** última fecha de actualización de la publicación 37 | **filas** número de filas del conjunto de datos, si aplica 38 | **columnas** número de columnas del conjunto de datos, si aplica 39 | **correo_contacto** correo de contacto de la entidad dueña de los datos 40 | **licencia** nombre de la licencia los datos 41 | **entidad** nombre de la entidad dueña de los datos 42 | **entidad_url** enlace web de la entidad dueña de los datos 43 | **entidad_sector** sector de la entidad 44 | **entidad_departamento** departamento de la entidad 45 | **entidad_orden** especifica si publicación es de orden territorial, nacional, departamental o internacional 46 | **entidad_dependencia** dependencia de la entidad dueña de los datos 47 | **entidad_municipio** municipio donde opera la entidad 48 | **actualizacion_frecuencia** frecuencia de actualización de los datos. Puede ser anual, semestral, mensual, trimestral, trianual, diaria, quinquenal, semanal, entre otros. También puede no aplicar 49 | **idioma** idioma en el que se encuentra la información 50 | **cobertura** alcance de la información. Puede ser nacional, departamental, municipal, centro poblado o internacional 51 | ============================== ============== 52 | 53 | 54 | Filtrar tabla inventario 55 | ++++++++++++++++++++++++ 56 | 57 | Búsqueda por términos clave 58 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 59 | 60 | Para hacer la búsqueda por términos clave, se construye un diccionario de Python que contenga como llaves los nombres de las columnas de texto de la tabla de inventario sobre las cuales se desea hacer el filtro. Los valores de cada llave es una lista que contiene uno o más términos clave. Este diccionario se ingresa al método :py:meth:`DatosGov.tabla_inventario` dentro del parámetro 'filtro'. 61 | 62 | Los términos que se ingresan al diccionario no tienen que tener tildes o mayúsculas que se encuentran en la columna original de la tabla de inventario. Por ejemplo, los resultados serán los mismos si se buscan las palabras 'Economía', 'economía', 'economia' o 'ECONOMÍA'. 63 | 64 | Abajo se encuentra un ejemplo donde se filtra la tabla de inventario por las columnas 'nombre' y 'tipo'. Dentro de la columna 'nombre' se busca si contiene los términos 'economia' o 'ambiente' y si la columna 'tipo' contiene el término 'conjunto de datos'. Es decir, se están buscando conjuntos de datos de temas de economía o ambiente. 65 | 66 | 67 | .. code-block:: python 68 | 69 | >>> # Se crea el diccionario con el filtro deseado 70 | >>> filtro = { 71 | >>> 'nombre': ['economia', 'ambiente'], 72 | >>> 'tipo': ['conjunto de datos'] 73 | >>> } 74 | 75 | >>> # Se abre la tabla de inventario con el filtro deseado 76 | >>> inventario = DatosGov().tabla_inventario(filtro=filtro) 77 | 78 | 79 | .. code-block:: python 80 | 81 | >>> # Se imprime la tabla de inventario con el filtro aplicado en la celda anterior 82 | >>> inventario 83 | 84 | ===== =========== ================================================= ================================================= ================================================= ============ ================= ================================ ================================================== ================================================ =================== === ================================================== ================================================== ================================== ==================== ============= ================================================= ================= ======================== ======= ============= 85 | index numero_api nombre descripcion dueno base_publica tipo categoria terminos_clave url fecha_creacion ... entidad entidad_url entidad_sector entidad_departamento entidad_orden entidad_dependencia entidad_municipio actualizacion_frecuencia idioma cobertura 86 | ===== =========== ================================================= ================================================= ================================================= ============ ================= ================================ ================================================== ================================================ =================== === ================================================== ================================================== ================================== ==================== ============= ================================================= ================= ======================== ======= ============= 87 | 4331 8w5c-54ny Economía del municipio La principal base de la economía del Municipio... Alcaldía Guatavita Si conjunto de datos Economía y Finanzas NaN https://www.datos.gov.co/d/8w5c-54ny 2018-09-28 20:35:26 ... NaN NaN Agricultura y Desarrollo Rural Cundinamarca Territorial Desarrollo económico Guatavita No aplica Español Municipal 88 | 5839 j7br-6yvm Contactos Sec. Ambiente Contactos en el departamento del Tolima para e... Carlos Alberto Sanchez Alfonso Si conjunto de datos Ambiente y Desarrollo Sostenible gobernacion,tolima,ambiente,contacto https://www.datos.gov.co/d/j7br-6yvm 2016-12-12 16:42:03 ... Gobernacion del Tolima NaN Ambiente y Desarrollo Sostenible Tolima Territorial Secretaría del Ambiente y Gestión Riesgo del T... Ibagué Anual Español Departamental 89 | 9952 bgmv-gnda AMBIENTE FÍSICO ANIMALES Caracterización de viviendas estrategia APS (a... Alcaldia de Pereira Secretaria TIC Si conjunto de datos Salud y Protección Social NaN https://www.datos.gov.co/d/bgmv-gnda 2019-12-03 13:28:54 ... Alcaldia de Pereira NaN Salud y Protección Social Risaralda Territorial Secretaria de Salud Pereira Anual Español Municipal 90 | 9982 8ffd-q6x9 AMBIENTE La consolidación de temas ambientales en el mu... ALCALDIADEPALESTINA Si conjunto de datos Ambiente y Desarrollo Sostenible ambiente https://www.datos.gov.co/d/8ffd-q6x9 2018-07-12 16:56:38 ... NaN NaN Ambiente y Desarrollo Sostenible Caldas Territorial PLANEACION Palestina Anual Español Municipal 91 | 17209 rm5b-5f33 AMBIENTE FISICO Caracterización de viviendas estrategia APS (a... Alcaldia de Pereira Secretaria TIC Si conjunto de datos Salud y Protección Social NaN https://www.datos.gov.co/d/rm5b-5f33 2019-12-03 13:37:29 ... Alcaldia de Pereira NaN Salud y Protección Social Risaralda Territorial Secretaria de Salud Pereira Anual Español Municipal 92 | 22681 8ffd-q6x9:0 AMBIENTE La consolidación de temas ambientales en el mu... ALCALDIADEPALESTINA No conjunto de datos Ambiente y Desarrollo Sostenible ambiente https://www.datos.gov.co/d/8ffd-q6x9/revisions/0 2021-03-04 14:43:12 ... NaN NaN Ambiente y Desarrollo Sostenible Caldas Territorial PLANEACION Palestina Anual Español Municipal 93 | 33255 q282-rcj5 Sector Economía Solidaria Registros de entidades pertenecientes al secto... Cámara de Comercio de Valledupar para el Valle... Si conjunto de datos NaN economía solidaria https://www.datos.gov.co/d/q282-rcj5 2020-11-04 16:01:05 ... Cámara de Comercio de Valledupar para el Valle... https://ccvalledupar.org.co/ No Aplica Cesar Territorial Registros Públicos Valledupar No aplica Español Departamental 94 | 34615 fwsu-jxw6 RELACION PROTOCOLOS DE BIOSEGURIDAD SECTORES D... RELACION PROTOCOLOS DE BIOSEGURIDAD SECTORES D... alcaldiarovira Si conjunto de datos Salud y Protección Social bioseguridad,rovira,protocolos https://www.datos.gov.co/d/fwsu-jxw6 2020-10-21 21:39:17 ... ALCALDIA DE ROVIRA NaN No Aplica Tolima Territorial SECRETARIA DE SALUD Rovira Anual Español Municipal 95 | 34628 3bvi-vpkx Indicadores de Economía y Productividad de Sab... Conozca indicadores de economía y productivida... Alcaldía de Sabaneta Si conjunto de datos Economía y Finanzas mercado laboral,comercio,economia,industria,in... https://www.datos.gov.co/d/3bvi-vpkx 2018-10-02 14:50:36 ... Alcaldía de Sabaneta http://www.otsabaneta.org/economia-y-productiv... No Aplica Antioquia Territorial Secretaría de Planeación y Desarrollo Territor... Sabaneta Anual Español Municipal 96 | ===== =========== ================================================= ================================================= ================================================= ============ ================= ================================ ================================================== ================================================ =================== === ================================================== ================================================== ================================== ==================== ============= ================================================= ================= ======================== ======= ============= 97 | 98 | 99 | Búsqueda por rango de filas y columnas 100 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 101 | 102 | Para hacer el filtro de la tabla de inventario por el tamaño de un conjunto de datos, se tiene que incluir el nombre de las columnas 'filas' y 'columnas' en el diccionario. Los valores de estas llaves son listas con dos elementos cada una: el primer elemento es el valor mínimo de filas o columnas y el segundo el valor máximo. 103 | 104 | A continuación se muestra un ejemplo de filtro, donde se seleccionan los conjuntos de datos con mínimo 50 filas y máximo 60 y con mínimo 8 columnas y máximo 10 105 | 106 | 107 | .. code-block:: python 108 | 109 | >>> # Se crea el diccionario con el filtro deseado 110 | >>> filtro = { 111 | >>> 'filas': [50, 60], 112 | >>> 'columnas': [8, 10] 113 | >>> } 114 | 115 | >>> # Se abre la tabla de inventario con el filtro deseado 116 | >>> inventario = DatosGov().tabla_inventario(filtro=filtro) 117 | 118 | 119 | .. code-block:: python 120 | 121 | >>> # Imprimir las columnas del código API, nombre, descripción, filas y columnas de la tabla de inventario filtrada 122 | >>> inventario[['numero_api', 'nombre', 'descripcion', 'filas', 'columnas']] 123 | 124 | 125 | ===== ========== ================================================== ================================================= ===== ======== 126 | index numero_api nombre descripcion filas columnas 127 | ===== ========== ================================================== ================================================= ===== ======== 128 | 55 igcu-56c4 CONTRATOS PRESTACION DE SERVICIOS 2018 MUNIC... Lista contratos de prestación de servicio al... 57.0 10.0 129 | 326 e9d5-9xvt Instituciones Educativas Extintas del Municipi... Información de las Instituciones Educativas qu... 58.0 10.0 130 | 367 vxhy-86k4 Ejecución Presupuestal a Junio de 2017 Acumulado de la ejecución presupuestal de la U... 56.0 9.0 131 | 421 hysn-yquu Publicidad registro de vallas Municipio de Pa... Registro de vallas publicitarias del Municipio... 53.0 8.0 132 | 519 8qip-sek5 Corregidores y Auxiliares Corregidores del Mun... Corregidores y Auxiliares o Ayudantes de Corre... 54.0 9.0 133 | ... ... ... ... ... ... 134 | 34281 svz2-ug32 Contratistas Alcaldía Mistrató 2021 Contiene datos del contratista como nombres y ... 50.0 9.0 135 | 34628 3bvi-vpkx Indicadores de Economía y Productividad de Sab... Conozca indicadores de economía y productivida... 57.0 10.0 136 | 34739 symc-8gre DOCENTES POR GENERO 2019-2 Docentes de planta, contrato y catedráticos cl... 59.0 8.0 137 | 34759 rubk-nymq Correos Institucionales Alcaldía de Copacabana Correos institucionales del municipio de Copac... 54.0 8.0 138 | 34808 9m2f-pdxx Licencias de Cannabis otorgadas por el Ministe... Licencias de uso de semillas para siembra, de ... 56.0 10.0 139 | ===== ========== ================================================== ================================================= ===== ======== 140 | 141 | 142 | Búsqueda por fecha 143 | ~~~~~~~~~~~~~~~~~~~ 144 | 145 | La tabla de inventario también puede filtrase por fecha. Para hacerlo, se ingresa el diccionario de filtro con una de las columnas de fecha y se especifican las fechas de inicio y de fin deseadas. El siguiente ejemplo muestra cómo obtener la tabla de inventario para publicaciones creadas entre el 1 de enero de 2020 y el 1 de febrero de 2020. 146 | 147 | .. code-block:: python 148 | 149 | >>> # Se crea el diccionario con el filtro deseado 150 | >>> filtro = { 151 | >>> 'fecha_creacion': ['2020-01-01', '2020-02-01'], 152 | >>> } 153 | 154 | >>> # Se abre la tabla de inventario con el filtro deseado 155 | >>> inventario = DatosGov().tabla_inventario(filtro=filtro) 156 | 157 | 158 | .. code-block:: python 159 | 160 | >>> # Se muestra la tabla filtrada por fecha 161 | >>> inventario 162 | 163 | 164 | 165 | ====== =========== ================================================= ================================================= ================================================= ============ ================= ================================ ================================================= ================================================ =================== === ================================================= ================================================= ================================ ==================== ============= ============================================= ================= ======================== ======= ============= 166 | index numero_api nombre descripcion dueno base_publica tipo categoria terminos_clave url fecha_creacion ... entidad entidad_url entidad_sector entidad_departamento entidad_orden entidad_dependencia entidad_municipio actualizacion_frecuencia idioma cobertura 167 | ====== =========== ================================================= ================================================= ================================================= ============ ================= ================================ ================================================= ================================================ =================== === ================================================= ================================================= ================================ ==================== ============= ============================================= ================= ======================== ======= ============= 168 | 104 k2sw-5j93:2 Atención al usuario año 2020 Instituto Municip... El ejercicio de caracterización de los usuario... IMETY No conjunto de datos Educación NaN https://www.datos.gov.co/d/k2sw-5j93/revisions/2 2020-01-23 19:49:39 ... Instituto Municipal de Educación para el Traba... NaN Educación Valle del Cauca Territorial Matricula Academica Yumbo Anual Español Departamental 169 | 106 5ex4-dqe9 Población estudiantil posgrado por semestre y/... Población estudiantil posgrado por semestre y/... Universidad Colegio Mayor de Cundinamarca Si conjunto de datos Educación programas académicos,posgrado,unicolmayor,univ... https://www.datos.gov.co/d/5ex4-dqe9 2020-01-21 17:05:26 ... Universidad Colegio Mayor de Cundinamarca http://www.unicolmayor.edu.co/portal/index.php... Educación Bogotá D.C. Nacional Oficina de Planeación, sistemas y desarrollo Bogotá D.C. Anual Español Nacional 170 | 331 wu3s-8hsw Población estudiantil pregrado por programa y ... Población estudiantil por programa y semestre ... Universidad Colegio Mayor de Cundinamarca Si conjunto de datos Educación estudiantes matriculados,programas académicos,... https://www.datos.gov.co/d/wu3s-8hsw 2020-01-21 15:35:30 ... Universidad Colegio Mayor de Cundinamarca http://www.unicolmayor.edu.co/portal/index.php... Educación Bogotá D.C. Nacional Oficina de Planeación, sistemas y desarrollo Bogotá D.C. Anual Español Nacional 171 | 498 6b2t-68uu:0 Entidades Públicas Municipio de El Hobo NaN Alcaldía de Hobo No conjunto de datos NaN NaN https://www.datos.gov.co/d/6b2t-68uu/revisions/0 2020-01-03 15:55:41 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 172 | 549 88ru-5pzs:0 MORBILIDAD 2019 NaN Capacitacion Mintic No conjunto de datos NaN NaN https://www.datos.gov.co/d/88ru-5pzs/revisions/0 2020-01-02 16:12:57 ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 173 | ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... 174 | 33666 ir4d-mzgr Publicaciones_E_Interacciones_Campaña_#Evoluci... La campaña #EvoluciónTransparente buscó conoce... urnadecristal Si conjunto de datos Participación ciudadana NaN https://www.datos.gov.co/d/ir4d-mzgr 2020-01-17 15:35:23 ... Urna de Cristal NaN No Aplica Bogotá D.C. Nacional Urna de Cristal Bogotá D.C. No aplica Español Nacional 175 | 34634 9et2-bf5i Entrega y Retoma Entrega y Retoma Ministerio TIC Oficina TI Gestión de Informacion Si conjunto de datos Ciencia, Tecnología e Innovación NaN https://www.datos.gov.co/d/9et2-bf5i 2020-01-27 21:17:01 ... Ministerio de Tecnologías de la Información y ... https://colombiatic.mintic.gov.co Ciencia, Tecnología e innovación Bogotá D.C. Nacional Dirección Computadores para Educar Bogotá D.C. Mensual Español Nacional 176 | 34660 fnir-e2zx DISCONTINUIDAD DISCONTINUIDAD SEPTIEMBRE 2020 EMPRESA IBAGUEREÑA DE ACUEDUCTO Y ALCANTARILLA... Si conjunto de datos Vivienda, Ciudad y Territorio NaN https://www.datos.gov.co/d/fnir-e2zx 2020-01-29 20:39:14 ... NaN NaN Vivienda Ciudad y Territorio Tolima Territorial GRUPO CALIDAD DE AGUA Ibagué Mensual Español Municipal 177 | 34690 syiu-8mvf PARQUE AUTOMOTOR DEL MUNICIPIO DE BARBOSA ANT... Contiene el inventario de vehículos registrad... Alcaldía de Barbosa - Antioquia Si conjunto de datos Transporte vehiculos,parque automotor https://www.datos.gov.co/d/syiu-8mvf 2020-01-16 19:19:56 ... NaN NaN Transporte Antioquia Territorial Secretaría de Movilidad Barbosa Anual Español Municipal 178 | 34780 etwv-wj8f Pueblos indígenas a nivel Nacional 2020 Información de la ubicación de los pueblos ind... Ministerio del Interior Si conjunto de datos NaN indígenas,dairm,etnias,pueblos https://www.datos.gov.co/d/etwv-wj8f 2020-01-27 14:47:31 ... Ministerio del Interior NaN Interior Bogotá D.C. Nacional Dirección de Asuntos Indígenas ROM y Minorías Bogotá D.C. Anual Español Nacional 179 | ====== =========== ================================================= ================================================= ================================================= ============ ================= ================================ ================================================= ================================================ =================== === ================================================= ================================================= ================================ ==================== ============= ============================================= ================= ======================== ======= ============= 180 | 181 | 182 | Abrir un conjunto de datos del Portal de Datos Abiertos 183 | ------------------------------------------------------- 184 | 185 | Para abrir un conjunto de datos.gov.co es necesario tener el código API de ese conjunto e ingresarlo al método :py:meth:`DatosGov.cargar_base`. Con esta función se crea un objeto que contiene el dataframe y el diccionario de metadatos del conjunto, los cuales se pueden obtener con los métodos 'to_dataframe' y 'metadatos' 186 | 187 | A continuación está el código para cargar el conjunto de datos de 'Pueblos indígenas a nivel Nacional 2020', el cual se encuentra en el último filtro de la tabla de inventario. 188 | 189 | 190 | Cargar conjunto de datos con número API 191 | +++++++++++++++++++++++++++++++++++++++ 192 | 193 | 194 | .. code-block:: python 195 | 196 | >>> # Se define la variable 'numero_api', que contiene el número API del conjunto 'Pueblos indígenas a nivel Nacional 2020' 197 | >>> numero_api = 'etwv-wj8f' 198 | 199 | >>> # Se descarga la información del conjunto de datos en la variable 'data' con el método 'cargar_base'. 200 | >>> # Al parámetro 'api_id' se asigna el número API y 'limite_filas' especifica que únicamente se descargan 200 filas del conjunto 201 | >>> data = DatosGov().cargar_base(api_id = numero_api, limite_filas=200) 202 | 203 | 204 | Obtener dataframe del conjunto de datos 205 | +++++++++++++++++++++++++++++++++++++++ 206 | 207 | 208 | .. code-block:: python 209 | 210 | >>> # Se obtiene el dataframe del conjunto de datos con el método 'to_dataframe' 211 | >>> datos = data.to_dataframe() 212 | 213 | >>> # Se visualiza una versión reducida del dataframe 214 | >>> datos 215 | 216 | 217 | ===== ============== =============== ================= 218 | index unnamed_column departamento pueblos_indigenas 219 | ===== ============== =============== ================= 220 | 0 NaN AMAZONAS KAWIYARI 221 | 1 NaN AMAZONAS SIONA 222 | 2 NaN AMAZONAS YAGUA 223 | 3 NaN AMAZONAS BARASANO 224 | 4 NaN AMAZONAS LETUAMA 225 | ... ... ... ... 226 | 195 NaN VALLE DEL CAUCA EMBERA CHAMI 227 | 196 NaN VALLE DEL CAUCA EPERARA SIAPIDARA 228 | 197 NaN VALLE DEL CAUCA NASA 229 | 198 NaN VALLE DEL CAUCA PASTO 230 | 199 NaN VALLE DEL CAUCA WAUNANN 231 | ===== ============== =============== ================= 232 | 233 | 234 | Obtener diccionario de metadatos del conjunto de datos 235 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 236 | 237 | .. code-block:: python 238 | 239 | >>> # Los metadatos se obtienen con el método 'metadatos' y se asignan a la variable 'meta' 240 | >>> meta = data.metadatos() 241 | 242 | >>> # Se visualiza el diccionario de metadatos 243 | >>> meta 244 | 245 | {'numero_api': 'etwv-wj8f', 246 | 'nombre': 'Pueblos indígenas a nivel Nacional 2020', 247 | 'descripcion': 'Información de la ubicación de los pueblos indígenas por departamento y municipio a 31 de Diciembre de 2020.', 248 | 'tipo': 'dataset', 249 | 'url': 'NA', 250 | 'categoria': 'NA', 251 | 'fecha_creacion': '2020-01-27', 252 | 'numero_vistas': 360, 253 | 'numero_descargas': 60, 254 | 'licencia': 'NA', 255 | 'fecha_publicacion': '2020-01-27', 256 | 'base_publica': 'published', 257 | 'fecha_actualizacion': '2021-01-26', 258 | 'numero_filas': 'NA', 259 | 'numero_columnas': 3, 260 | 'licencia_url': 'http://creativecommons.org/licenses/by-sa/4.0/legalcode', 261 | 'entidad': 'Ministerio del Interior', 262 | 'entidad_municipio': 'Bogotá D.C.', 263 | 'entidad_sector': 'Interior', 264 | 'entidad_departamento': 'Bogotá D.C.', 265 | 'entidad_orden': 'Nacional', 266 | 'entidad_dependencia': 'Dirección de Asuntos Indígenas ROM y Minorías', 267 | 'cobertura': 'Nacional', 268 | 'idioma': 'Español', 269 | 'frecuencia_actualizacion': 'Anual', 270 | 'dueno': 'Ministerio del Interior', 271 | 'columnas': {'Unnamed Column': {'tipo': 'text', 272 | 'descripcion': '', 273 | 'nombre_df': 'unnamed_column'}, 274 | 'DEPARTAMENTO': {'tipo': 'text', 275 | 'descripcion': '', 276 | 'nombre_df': 'departamento'}, 277 | 'PUEBLOS INDIGENAS': {'tipo': 'text', 278 | 'descripcion': '', 279 | 'nombre_df': 'pueblos_indigenas'}}} 280 | -------------------------------------------------------------------------------- /leila/templates/template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 10 | {{ title }} 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 51 | 52 | 53 |
    54 | 55 |
    56 |
    57 |
    58 | 59 | 60 |
    61 |
    62 |

    {{ title }}

    63 | Reporte generado automáticamente {{ current_time }} 64 |
    65 |
    66 | 67 |
    68 | 69 | 70 | {% if html_metadatos_full != None %} 71 |
    72 |
    73 | 74 |
    75 |
    76 | {% if link_datos_abiertos != 'NA' %} 77 |

    Metadatos - ver en Datos Abiertos

    78 | {% else %} 79 |

    Metadatos

    80 | {% endif %} 81 |
    82 |
    83 | 84 | 88 | 89 |
    90 | 91 |
    92 |
    93 | 100 | 112 |
    113 | 114 | 115 |
    116 |
    117 |
    118 | 119 |
    120 |
    121 | {{ html_descr_col_meta }} 122 |
    123 |
    124 |
    125 |
    126 | 127 |
    128 |
    129 |
    130 |
    131 | {% endif %} 132 | 133 | 134 | {% if generales %} 135 |
    136 |
    137 |
    138 |
    139 |

    Estadísticas generales

    140 |
    141 |
    142 | 149 | 161 |
    162 |
    163 |
    164 | {% endif %} 165 | 166 | 167 | {% if muestra_datos %} 168 |
    169 |
    170 | 171 |

    Muestra de datos

    172 | 176 | 177 |
    178 | 179 |
    180 |
    181 |
    182 | {{ html_dataframe_head }} 183 |
    184 |
    185 | 186 | 187 |
    188 |
    189 |
    190 | {{ html_dataframe_tail }} 191 |
    192 |
    193 |
    194 |
    {{ dataframe_shape }}

    195 |
    196 |
    197 |
    198 | {% endif %} 199 | 200 | 201 | {% if seccion_especificas %} 202 |
    203 |
    204 | 205 |

    Estadísticas específicas

    206 | 223 | 224 |
    225 | 226 | {% if especificas_tipo %} 227 | {% if especificas_active == 'tipo' %} 228 |
    229 | {% else %} 230 |
    231 | {% endif %} 232 |
    233 |

    234 | Aquí se muestran los tipos de las columnas del conjunto de datos con tres metodologías diferentes. La columna 'Tipo general' muestra si las variables son numéricas, de texto, booleanas; la columna 'Tipo general (Python)' muestra el tipo de la variable según la función "dtypes" de Python; las columnas 'Tipo especifico' muestran los tipos de las observaciones de cada columna, incluidos datos faltantes ("nan"), como porcentaje del total. 235 |

    236 |
    237 | 238 |
    239 |

    Variables

    240 |

    Seleccionar todos

    241 | {% for item in variables_list_2 %} 242 |

    {{ loop.index }} - {{ item }}

    243 | {% endfor %} 244 |
    245 |
    246 | 247 | 248 | 249 | 250 | {% for item in header_list_2 %} 251 | 252 | {% endfor %} 253 | 254 | 255 | 256 | {% for row in items_2%} 257 | 258 | {% for column in row %} 259 | {% if loop.index0 == 0 %} 260 | 261 | {% else %} 262 | 263 | {% endif %} 264 | {% endfor %} 265 | 266 | {% endfor %} 267 | 268 |
    Variable{{ item }}
    {{ column }}{{ column }}
    269 |
    270 |
    271 |
    272 | {% endif %} 273 | 274 | 275 | {% if especificas_frecuencias%} 276 | {% if especificas_active == 'frecuencias' %} 277 |
    278 | {% else %} 279 |
    280 | {% endif %} 281 |
    282 |

    283 | Contiene las 10 categorías más frecuentes de las columnas tipo texto y presenta el porcentaje dentro del total de observaciones. Incluye valores faltantes. 284 |

    285 |
    286 | 287 |
    288 |

    Variables

    289 |

    Seleccionar todos

    290 | {% for item in variables_list_3 %} 291 |

    {{ loop.index }} - {{ item }}

    292 | {% endfor %} 293 |
    294 |
    295 | 296 | 297 | 298 | {% for item in columnas_list_3 %} 299 | 300 | {% endfor %} 301 | 302 | 303 | 304 | {% for row in items_3%} 305 | 306 | {% for column in row %} 307 | {% if loop.index0 == 0 %} 308 | 309 | {% else %} 310 | 311 | {% endif %} 312 | {% endfor %} 313 | 314 | {% endfor %} 315 | 316 |
    {{ item }}
    {{ column }}{{ column }}
    317 |
    318 |
    319 |
    320 | {% endif %} 321 | 322 | 323 | {% if especificas_duplicados_filas or especificas_duplicados_columnas %} 324 | {% if especificas_active == 'duplicados' %} 325 |
    326 | {% else %} 327 |
    328 | {% endif %} 329 |
    330 |

    331 | Cada columna muestra los nombres de las filas y columnas que están duplicadas en el conjunto de datos.{{ mensaje_duplicados }} 332 |

    333 |
    334 |
    335 | 345 |
    346 | 347 | 348 | {% if especificas_duplicados_filas %} 349 |
    350 |
    351 | {% if html_dataframe_duplic_filas != None %} 352 |
    353 | {{ html_dataframe_duplic_filas }} 354 |
    355 | {% else %} 356 | * El conjunto de datos no contiene filas duplicadas 357 | {% endif %} 358 |
    359 | {% endif %} 360 | 361 | 362 | {% if especificas_duplicados_columnas %} 363 | {% if especificas_duplicados_filas %} 364 |
    365 | {% else %} 366 |
    367 | {% endif %} 368 |
    369 | {% if html_dataframe_duplic_colum != None %} 370 |
    371 | {{ html_dataframe_duplic_colum }} 372 |
    373 | {% else %} 374 | * El conjunto de datos no contiene columnas duplicadas 375 | {% endif %} 376 |
    377 | {% endif %} 378 | 379 |
    380 |
    381 |
    382 |
    383 | {% endif %} 384 | 385 | 386 | {% if especificas_descriptivas %} 387 | {% if especificas_active == 'descriptivas' %} 388 |
    389 | {% else %} 390 |
    391 | {% endif %} 392 |
    393 |

    394 | Contiene información para cada columna de tipo numérico, incluye media, mediana, percentiles, desviación estándar, valores extremos y porcentaje de valores faltantes. 395 |

    396 | {% if variables_list != None %} 397 |
    398 |
    399 |

    Variables

    400 |

    Seleccionar todos

    401 | {% for item in variables_list %} 402 |

    {{ loop.index }} - {{ item }}

    403 | {% endfor %} 404 |
    405 |
    406 | 407 | 408 | 409 | 410 | {% for item in header_list %} 411 | 412 | {% endfor %} 413 | 414 | 415 | 416 | {% for row in items%} 417 | 418 | {% for column in row %} 419 | {% if loop.index0 == 0 %} 420 | 421 | {% else %} 422 | 423 | {% endif %} 424 | {% endfor %} 425 | 426 | {% endfor %} 427 | 428 |
    Variable{{ item }}
    {{ column }}{{ column }}
    429 |
    430 |
    431 | {% else %} 432 | * El conjunto de datos no tiene columnas numéricas 433 | {% endif %} 434 |
    435 | {% endif %} 436 |
    437 |
    438 |
    439 |
    440 |
    441 | {% endif %} 442 | 443 | 444 | {% if seccion_correlaciones %} 445 |
    446 |
    447 | 448 |

    Correlaciones

    449 | 466 | 467 |
    468 | 469 | 470 | {% if corre_pearson_values != None %} 471 | {% if correlaciones_active == 'pearson' %} 472 |
    473 | {% else %} 474 |
    475 | {% endif %} 476 |
    477 |

    478 | La correlación de Pearson es una medida de correlación lineal entre dos variables. Varía entre -1 y 1, donde -1 significa que la correlación entre las variables es negativa y total, 0 que no existe la correlación y 1 que hay correlación positiva total. Se calcula como la división de la covarianza de las dos variables con el producto de las desviaciones estándar de cada variable. 479 |

    480 | {% if corre_pearson_headers|length > 1 %} 481 |
    482 |
    483 |
    484 |
    485 |
    486 |
    487 |
    488 |

    * En caso de ver mal los labels del eje x, ajustar el zoom del navegador.


    489 | {% else %} 490 |

    * El conjunto de datos no tiene columnas numéricas para el cálculo de correlaciones

    491 | {% endif %} 492 |
    493 | {% endif %} 494 | 495 | 496 | {% if corre_kendall_values != None %} 497 | {% if correlaciones_active == 'kendall' %} 498 |
    499 | {% else %} 500 |
    501 | {% endif %} 502 |
    503 |

    504 | La correlación de Kendall mide la relación entre dos variables ordinales. Varía entre -1 y 1, donde -1 significa que la correlación entre las variables es negativa total, 0 que no existe la correlación y 1 que hay correlación positiva total. Se calcula como la división de los números concordantes menos los discordantes de pares entre las variables con el número total de pares. 505 |

    506 | {% if corre_kendall_headers|length > 1 %} 507 |
    508 |
    509 |
    510 |
    511 |
    512 |
    513 |
    514 |

    * En caso de ver mal los labels del eje x, ajustar el zoom del navegador.


    515 | {% else %} 516 |

    * El conjunto de datos no tiene columnas numéricas para el cálculo de correlaciones

    517 | {% endif %} 518 |
    519 | {% endif %} 520 | 521 | 522 | {% if corre_spearman_values != None %} 523 | {% if correlaciones_active == 'spearman' %} 524 |
    525 | {% else %} 526 |
    527 | {% endif %} 528 |
    529 |

    530 | La correlación de Spearman es una medida de correlación monotónica que se usa principalmente para medir la relación entre dos variables ordinales. Varía entre -1 y 1, donde -1 significa una correlación monotónica negativa total, 0 que no hay correlación monotónica y 1 que hay una correlación monotónica positiva total. Se calcula como la división de la covarianza de los rangos de cada variable con el producto de las desviaciones estándar de cada variable. 531 |

    532 | {% if corre_spearman_headers|length > 1 %} 533 |
    534 |
    535 |
    536 |
    537 |
    538 |
    539 |
    540 |

    * En caso de ver mal los labels del eje x, ajustar el zoom del navegador.


    541 | {% else %} 542 |

    * El conjunto de datos no tiene columnas numéricas para el cálculo de correlaciones

    543 | {% endif %} 544 |
    545 | {% endif %} 546 | 547 | 548 | {% if corre_cramer_values != None %} 549 | {% if correlaciones_active == 'cramer' %} 550 |
    551 | {% else %} 552 |
    553 | {% endif %} 554 |
    555 |

    556 | La correlación Cramer V se usas para medir la relación entre dos variables nominales. Varía entre 0 y 1, donde 0 significa que no hay correlación y 1 que la correlación es positiva y total. Se calcula como la raíz cuadrada de la división de estadístico Chi Cuadrado con el mínimo entre el número de filas o columnas y el número total de observaciones. 557 |

    558 | {% if corre_cramer_headers|length > 1 %} 559 |
    560 |
    561 |
    562 |
    563 |
    564 |
    565 |
    566 |

    * En caso de ver mal los labels del eje x, ajustar el zoom del navegador.


    567 | {% else %} 568 |

    * El conjunto de datos no tiene columnas categóricas para el cálculo de correlaciones

    569 | {% endif %} 570 |
    571 | {% endif %} 572 | 573 | 574 | {% if corre_phik_values != None %} 575 | {% if correlaciones_active == 'phik' %} 576 |
    577 | {% else %} 578 |
    579 | {% endif %} 580 |
    581 |

    582 | Esta correlación se calcula con el módulo Phik de Python. ver más detalles 583 |

    584 | {% if corre_phik_headers|length > 1 %} 585 |
    586 |
    587 |
    588 |
    589 |
    590 |
    591 |
    592 |

    * En caso de ver mal los labels del eje x, ajustar el zoom del navegador.


    593 | {% else %} 594 |

    * El conjunto de datos no tiene columnas categóricas para el cálculo de correlaciones

    595 | {% endif %} 596 |
    597 | {% endif %} 598 | 599 |
    600 |
    601 |
    602 | {% endif %} 603 | 604 | 605 |
    606 |
    607 | 614 |
    615 |
    616 | 617 | 618 | 627 | 628 | 629 | 654 | 655 | 672 | 673 | 688 | 689 | 690 | 715 | 716 | 733 | 734 | 749 | 750 | 751 | 776 | 777 | 794 | 795 | 810 | 811 | 812 | {% if seccion_correlaciones %} 813 | 849 | 850 | 874 | {% endif %} 875 | 876 | 893 | 894 |
    895 |
    896 |
    897 |
    898 | 899 | --------------------------------------------------------------------------------