"[Fuente original del Notebook de *Data Science: Introduction to Machine Learning for Data Science Python and Machine Learning Studio por Lee Stott*](https://github.com/leestott/intro-Datascience/blob/master/Course%20Materials/4-Cleaning_and_Manipulating-Reference.ipynb)\n",
"[Fuente original del cuaderno de *Data Science: Introduction to Machine Learning for Data Science Python and Machine Learning Studio por Lee Stott*](https://github.com/leestott/intro-Datascience/blob/master/Course%20Materials/4-Cleaning_and_Manipulating-Reference.ipynb)\n",
"\n",
"## Explorando información de `DataFrame`\n",
"\n",
"> **Objetivo de aprendizaje:** Al final de esta subsección, deberías sentirte cómodo encontrando información general sobre los datos almacenados en pandas DataFrames.\n",
"> **Objetivo de aprendizaje:** Al final de esta subsección, deberías sentirte cómodo encontrando información general sobre los datos almacenados en DataFrames de pandas.\n",
"\n",
"Una vez que hayas cargado tus datos en pandas, lo más probable es que estén en un `DataFrame`. Sin embargo, si el conjunto de datos en tu `DataFrame` tiene 60,000 filas y 400 columnas, ¿cómo puedes empezar a entender con qué estás trabajando? Afortunadamente, pandas proporciona herramientas convenientes para observar rápidamente información general sobre un `DataFrame`, además de las primeras y últimas filas.\n",
"Una vez que hayas cargado tus datos en pandas, lo más probable es que estén en un `DataFrame`. Sin embargo, si el conjunto de datos en tu `DataFrame` tiene 60,000 filas y 400 columnas, ¿cómo puedes siquiera empezar a entender con qué estás trabajando? Afortunadamente, pandas proporciona herramientas convenientes para observar rápidamente información general sobre un `DataFrame`, además de las primeras y últimas filas.\n",
"\n",
"Para explorar esta funcionalidad, importaremos la biblioteca Python scikit-learn y utilizaremos un conjunto de datos icónico que todo científico de datos ha visto cientos de veces: el conjunto de datos *Iris* del biólogo británico Ronald Fisher, utilizado en su artículo de 1936 \"El uso de mediciones múltiples en problemas taxonómicos\":\n"
]
@ -78,9 +78,9 @@
"id": "smE7AGzOhxk2"
},
"source": [
"Entonces, estamos trabajando con 150 filas y 4 columnas de datos. Cada fila representa un punto de datos y cada columna representa una característica asociada al marco de datos. Básicamente, hay 150 puntos de datos que contienen 4 características cada uno.\n",
"Entonces, estamos trabajando con 150 filas y 4 columnas de datos. Cada fila representa un punto de datos y cada columna representa una característica única asociada con el marco de datos. Básicamente, hay 150 puntos de datos que contienen 4 características cada uno.\n",
"\n",
"`shape` aquí es un atributo del marco de datos y no una función, por lo que no termina con un par de paréntesis.\n"
"`shape` aquí es un atributo del marco de datos y no una función, por eso no termina con un par de paréntesis.\n"
]
},
{
@ -90,7 +90,7 @@
},
"source": [
"### `DataFrame.columns`\n",
"Pasemos ahora a las 4 columnas de datos. ¿Qué representa exactamente cada una de ellas? El atributo `columns` nos dará el nombre de las columnas en el dataframe.\n"
"Ahora pasemos a las 4 columnas de datos. ¿Qué representa exactamente cada una de ellas? El atributo `columns` nos dará el nombre de las columnas en el dataframe.\n"
]
},
{
@ -181,8 +181,8 @@
},
"source": [
"A partir de aquí, podemos hacer algunas observaciones: \n",
"1. El tipo de dato de cada columna: En este conjunto de datos, toda la información está almacenada como números de punto flotante de 64 bits. \n",
"2. Número de valores no nulos: Manejar valores nulos es un paso importante en la preparación de datos. Esto se abordará más adelante en el cuaderno. \n"
"1. El tipo de dato de cada columna: En este conjunto de datos, todos los datos están almacenados como números de punto flotante de 64 bits. \n",
"2. Número de valores no nulos: Manejar los valores nulos es un paso importante en la preparación de datos. Esto se abordará más adelante en el cuaderno. \n"
]
},
{
@ -192,7 +192,7 @@
},
"source": [
"### DataFrame.describe()\n",
"Supongamos que tenemos muchos datos numéricos en nuestro conjunto de datos. Los cálculos estadísticos univariados, como la media, la mediana, los cuartiles, etc., se pueden realizar en cada una de las columnas de forma individual. La función `DataFrame.describe()` nos proporciona un resumen estadístico de las columnas numéricas de un conjunto de datos.\n"
"Supongamos que tenemos muchos datos numéricos en nuestro conjunto de datos. Los cálculos estadísticos univariados, como la media, la mediana, los cuartiles, etc., se pueden realizar en cada una de las columnas individualmente. La función `DataFrame.describe()` nos proporciona un resumen estadístico de las columnas numéricas de un conjunto de datos.\n"
]
},
{
@ -452,7 +452,7 @@
"source": [
"### Ejercicio:\n",
"\n",
"A partir del ejemplo dado anteriormente, queda claro que, por defecto, `DataFrame.head` devuelve las primeras cinco filas de un `DataFrame`. En la celda de código a continuación, ¿puedes encontrar una forma de mostrar más de cinco filas?\n"
"Del ejemplo dado anteriormente, queda claro que, por defecto, `DataFrame.head` devuelve las primeras cinco filas de un `DataFrame`. En la celda de código a continuación, ¿puedes encontrar una manera de mostrar más de cinco filas?\n"
]
},
{
@ -584,7 +584,7 @@
"source": [
"En la práctica, es útil poder examinar fácilmente las primeras filas o las últimas filas de un `DataFrame`, especialmente cuando estás buscando valores atípicos en conjuntos de datos ordenados.\n",
"\n",
"Todas las funciones y atributos mostrados anteriormente con la ayuda de ejemplos de código nos ayudan a obtener una visión general y una sensación del conjunto de datos.\n",
"Todas las funciones y atributos mostrados anteriormente con la ayuda de ejemplos de código nos ayudan a obtener una visión general y una idea del contenido de los datos.\n",
"\n",
"> **Conclusión:** Incluso solo mirando los metadatos sobre la información en un DataFrame o los primeros y últimos valores en uno, puedes obtener una idea inmediata sobre el tamaño, la forma y el contenido de los datos con los que estás trabajando.\n"
]
@ -595,18 +595,18 @@
"id": "TvurZyLSDxq_"
},
"source": [
"### Datos Faltantes\n",
"Vamos a profundizar en los datos faltantes. Los datos faltantes ocurren cuando no se almacena un valor en algunas de las columnas.\n",
"### Datos faltantes\n",
"Vamos a profundizar en los datos faltantes. Los datos faltantes ocurren cuando no se almacena ningún valor en algunas de las columnas.\n",
"\n",
"Tomemos un ejemplo: supongamos que alguien está consciente de su peso y no completa el campo de peso en una encuesta. Entonces, el valor del peso para esa persona estará ausente.\n",
"Tomemos un ejemplo: supongamos que alguien está preocupado por su peso y no completa el campo de peso en una encuesta. Entonces, el valor de peso para esa persona en particular estará ausente.\n",
"\n",
"La mayoría de las veces, en conjuntos de datos del mundo real, ocurren valores faltantes.\n",
"\n",
"**Cómo Pandas maneja los datos faltantes**\n",
"\n",
"Pandas maneja los valores faltantes de dos maneras. La primera, que ya has visto en secciones anteriores, es `NaN`, o Not a Number (No es un número). Este es en realidad un valor especial que forma parte de la especificación de punto flotante IEEE y se utiliza únicamente para indicar valores de punto flotante faltantes.\n",
"Pandas maneja los valores faltantes de dos maneras. La primera ya la has visto en secciones anteriores: `NaN`, o Not a Number (No es un número). Este es, de hecho, un valor especial que forma parte de la especificación de punto flotante IEEE y se utiliza únicamente para indicar valores faltantes de tipo flotante.\n",
"\n",
"Para los valores faltantes que no son de tipo flotante, pandas utiliza el objeto `None` de Python. Aunque pueda parecer confuso encontrarse con dos tipos diferentes de valores que esencialmente indican lo mismo, hay razones programáticas sólidas para esta elección de diseño y, en la práctica, seguir este enfoque permite a pandas ofrecer un buen compromiso en la gran mayoría de los casos. No obstante, tanto `None` como `NaN` tienen restricciones que debes tener en cuenta en relación con cómo pueden ser utilizados.\n"
"Para valores faltantes que no son de tipo flotante, pandas utiliza el objeto `None` de Python. Aunque pueda parecer confuso encontrarse con dos tipos diferentes de valores que esencialmente indican lo mismo, hay razones programáticas sólidas para esta elección de diseño y, en la práctica, seguir este enfoque permite a pandas ofrecer un buen equilibrio para la gran mayoría de los casos. No obstante, tanto `None` como `NaN` tienen restricciones que debes tener en cuenta con respecto a cómo pueden ser utilizados.\n"
]
},
{
@ -616,7 +616,7 @@
},
"source": [
"### `None`: datos faltantes no flotantes\n",
"Debido a que `None` proviene de Python, no puede ser utilizado en arrays de NumPy y pandas que no tengan el tipo de dato `'object'`. Recuerda, los arrays de NumPy (y las estructuras de datos en pandas) solo pueden contener un tipo de dato. Esto es lo que les da su enorme poder para trabajar con datos y cálculos a gran escala, pero también limita su flexibilidad. Dichos arrays tienen que convertir los datos al \"denominador común más bajo\", es decir, al tipo de dato que abarque todo en el array. Cuando `None` está en el array, significa que estás trabajando con objetos de Python.\n",
"Dado que `None` proviene de Python, no puede ser utilizado en arrays de NumPy y pandas que no tengan el tipo de dato `'object'`. Recuerda que los arrays de NumPy (y las estructuras de datos en pandas) solo pueden contener un tipo de dato. Esto es lo que les da su enorme potencia para trabajar con datos y cálculos a gran escala, pero también limita su flexibilidad. Dichos arrays tienen que convertir su tipo al \"mínimo común denominador\", es decir, al tipo de dato que abarque todo en el array. Cuando `None` está en el array, significa que estás trabajando con objetos de Python.\n",
"\n",
"Para ver esto en acción, considera el siguiente ejemplo de array (nota el `dtype` que tiene):\n"
]
@ -657,7 +657,7 @@
"id": "pdlgPNbhgRr7"
},
"source": [
"La realidad de los tipos de datos promovidos conlleva dos efectos secundarios. Primero, las operaciones se realizarán a nivel de código interpretado de Python en lugar de código compilado de NumPy. Básicamente, esto significa que cualquier operación que involucre `Series` o `DataFrames` con `None` será más lenta. Aunque probablemente no notarías esta disminución de rendimiento, en conjuntos de datos grandes podría convertirse en un problema.\n",
"La realidad de los tipos de datos promovidos conlleva dos efectos secundarios. Primero, las operaciones se realizarán a nivel de código interpretado de Python en lugar de código compilado de NumPy. Básicamente, esto significa que cualquier operación que involucre `Series` o `DataFrames` con `None` será más lenta. Aunque probablemente no notarías este impacto en el rendimiento, en conjuntos de datos grandes podría convertirse en un problema.\n",
"\n",
"El segundo efecto secundario deriva del primero. Debido a que `None` esencialmente arrastra a las `Series` o `DataFrames` de vuelta al mundo de Python estándar, usar agregaciones de NumPy/pandas como `sum()` o `min()` en arreglos que contienen un valor ``None`` generalmente producirá un error:\n"
]
@ -697,7 +697,9 @@
"metadata": {
"id": "LcEwO8UogRr9"
},
"source": []
"source": [
"**Conclusión clave**: La suma (y otras operaciones) entre enteros y valores `None` no está definida, lo que puede limitar lo que puedes hacer con conjuntos de datos que los contienen.\n"
]
},
{
"cell_type": "markdown",
@ -828,7 +830,9 @@
"metadata": {
"id": "_iDvIRC8gRsA"
},
"source": []
"source": [
"Recuerda: `NaN` es solo para valores de punto flotante faltantes; no hay un equivalente de `NaN` para enteros, cadenas o valores booleanos.\n"
]
},
{
"cell_type": "markdown",
@ -902,14 +906,14 @@
"id": "WjMQwltNgRsB"
},
"source": [
"En el proceso de convertir tipos de datos para establecer homogeneidad en los `Series` y `DataFrame`s, pandas cambiará sin problemas los valores faltantes entre `None` y `NaN`. Debido a esta característica de diseño, puede ser útil pensar en `None` y `NaN` como dos variantes diferentes de \"nulo\" en pandas. De hecho, algunos de los métodos principales que usarás para manejar valores faltantes en pandas reflejan esta idea en sus nombres:\n",
"En el proceso de convertir tipos de datos para establecer homogeneidad en los datos de `Series` y `DataFrame`s, pandas cambiará sin problema los valores faltantes entre `None` y `NaN`. Debido a esta característica de diseño, puede ser útil pensar en `None` y `NaN` como dos variantes diferentes de \"nulo\" en pandas. De hecho, algunos de los métodos principales que usarás para manejar valores faltantes en pandas reflejan esta idea en sus nombres:\n",
"\n",
"- `isnull()`: Genera una máscara booleana que indica valores faltantes\n",
"- `notnull()`: Opuesto a `isnull()`\n",
"- `dropna()`: Devuelve una versión filtrada de los datos\n",
"- `fillna()`: Devuelve una copia de los datos con los valores faltantes rellenados o imputados\n",
"- `isnull()`: Genera una máscara booleana que indica valores faltantes.\n",
"- `notnull()`: Opuesto a `isnull()`.\n",
"- `dropna()`: Devuelve una versión filtrada de los datos.\n",
"- `fillna()`: Devuelve una copia de los datos con los valores faltantes rellenados o imputados.\n",
"\n",
"Estos son métodos importantes que debes dominar y con los que debes familiarizarte, así que repasémoslos en detalle.\n"
"Estos son métodos importantes que debes dominar y con los que debes sentirte cómodo, así que vamos a repasarlos en detalle.\n"
]
},
{
@ -920,8 +924,7 @@
"source": [
"### Detectar valores nulos\n",
"\n",
"Ahora que hemos entendido la importancia de los valores faltantes, necesitamos detectarlos en nuestro conjunto de datos antes de manejarlos. \n",
"Tanto `isnull()` como `notnull()` son tus métodos principales para detectar datos nulos. Ambos devuelven máscaras booleanas sobre tus datos.\n"
"Ahora que hemos entendido la importancia de los valores faltantes, necesitamos detectarlos en nuestro conjunto de datos antes de manejarlos. Tanto `isnull()` como `notnull()` son tus métodos principales para detectar datos nulos. Ambos devuelven máscaras booleanas sobre tus datos.\n"
]
},
{
@ -974,7 +977,7 @@
"id": "PaSZ0SQygRsC"
},
"source": [
"Mira detenidamente el contenido. ¿Hay algo que te sorprenda? Aunque `0` es un nulo aritmético, sigue siendo un número entero perfectamente válido, y pandas lo trata como tal. `''` es un poco más sutil. Aunque lo usamos en la Sección 1 para representar un valor de cadena vacío, sigue siendo un objeto de cadena y no una representación de nulo según pandas.\n",
"Observa detenidamente el resultado. ¿Hay algo que te sorprenda? Aunque `0` es un valor nulo en términos aritméticos, sigue siendo un número entero válido y pandas lo trata como tal. `''` es un caso un poco más sutil. Aunque lo usamos en la Sección 1 para representar un valor de cadena vacío, sigue siendo un objeto de tipo cadena y no una representación de un valor nulo según pandas.\n",
"\n",
"Ahora, vamos a darle la vuelta y usar estos métodos de una manera más parecida a cómo los usarás en la práctica. Puedes usar máscaras booleanas directamente como un índice de ``Series`` o ``DataFrame``, lo cual puede ser útil cuando intentas trabajar con valores faltantes (o presentes) de forma aislada.\n",
"\n",
@ -1071,7 +1074,7 @@
"\n",
"La cantidad de datos que pasamos a nuestro modelo tiene un efecto directo en su rendimiento. Eliminar valores nulos significa que estamos reduciendo el número de puntos de datos y, por lo tanto, el tamaño del conjunto de datos. Por eso, es recomendable eliminar filas con valores nulos cuando el conjunto de datos es bastante grande.\n",
"\n",
"Otro caso podría ser que una fila o columna específica tenga muchos valores faltantes. En ese caso, podrían eliminarse porque no aportarían mucho valor a nuestro análisis, ya que la mayor parte de los datos están ausentes para esa fila/columna.\n",
"Otro caso podría ser que una fila o columna específica tenga muchos valores faltantes. En ese caso, podrían eliminarse porque no aportarían mucho valor a nuestro análisis, ya que la mayoría de los datos están ausentes para esa fila/columna.\n",
"\n",
"Más allá de identificar valores faltantes, pandas ofrece una forma conveniente de eliminar valores nulos de `Series` y `DataFrame`s. Para ver esto en acción, volvamos a `example3`. La función `DataFrame.dropna()` ayuda a eliminar las filas con valores nulos.\n"
]
@ -1112,9 +1115,9 @@
"id": "hil2cr64gRsD"
},
"source": [
"Ten en cuenta que esto debería verse como tu salida de `example3[example3.notnull()]`. La diferencia aquí es que, en lugar de simplemente indexar los valores enmascarados, `dropna` ha eliminado esos valores faltantes del `Series` `example3`.\n",
"Ten en cuenta que esto debería parecerse a tu salida de `example3[example3.notnull()]`. La diferencia aquí es que, en lugar de simplemente indexar los valores enmascarados, `dropna` ha eliminado esos valores faltantes del `Series` `example3`.\n",
"\n",
"Debido a que los DataFrames tienen dos dimensiones, ofrecen más opciones para eliminar datos.\n"
"Dado que los DataFrames tienen dos dimensiones, ofrecen más opciones para eliminar datos.\n"
]
},
{
@ -1206,7 +1209,7 @@
"source": [
"(¿Notaste que pandas convirtió dos de las columnas a flotantes para acomodar los `NaN`?)\n",
"\n",
"No puedes eliminar un solo valor de un `DataFrame`, por lo que tienes que eliminar filas o columnas completas. Dependiendo de lo que estés haciendo, podrías querer hacer una cosa u otra, y por eso pandas te da opciones para ambas. Dado que en ciencia de datos las columnas generalmente representan variables y las filas representan observaciones, es más probable que elimines filas de datos; la configuración predeterminada de `dropna()` es eliminar todas las filas que contengan cualquier valor nulo:\n"
"No puedes eliminar un único valor de un `DataFrame`, por lo que tienes que eliminar filas o columnas completas. Dependiendo de lo que estés haciendo, podrías querer hacer una u otra cosa, y por eso pandas te da opciones para ambas. Debido a que en ciencia de datos las columnas generalmente representan variables y las filas representan observaciones, es más probable que elimines filas de datos; la configuración predeterminada de `dropna()` es eliminar todas las filas que contienen cualquier valor nulo:\n"
]
},
{
@ -1358,9 +1361,9 @@
"id": "KWXiKTfMgRsF"
},
"source": [
"Ten en cuenta que esto puede eliminar una gran cantidad de datos que podrías querer conservar, especialmente en conjuntos de datos más pequeños. ¿Qué pasa si solo quieres eliminar filas o columnas que contienen varios o incluso todos los valores nulos? Puedes especificar esas configuraciones en `dropna` con los parámetros `how` y `thresh`.\n",
"Ten en cuenta que esto puede eliminar muchos datos que podrías querer conservar, especialmente en conjuntos de datos más pequeños. ¿Qué pasa si solo quieres eliminar filas o columnas que contienen varios o incluso todos los valores nulos? Puedes especificar esas configuraciones en `dropna` utilizando los parámetros `how` y `thresh`.\n",
"\n",
"Por defecto, `how='any'` (si deseas comprobarlo por ti mismo o ver qué otros parámetros tiene el método, ejecuta `example4.dropna?` en una celda de código). Alternativamente, podrías especificar `how='all'` para eliminar únicamente las filas o columnas que contienen todos los valores nulos. Ampliemos nuestro ejemplo de `DataFrame` para ver esto en acción en el próximo ejercicio.\n"
"Por defecto, `how='any'` (si deseas verificarlo por ti mismo o ver qué otros parámetros tiene el método, ejecuta `example4.dropna?` en una celda de código). Alternativamente, podrías especificar `how='all'` para eliminar únicamente las filas o columnas que contienen todos los valores nulos. Vamos a ampliar nuestro ejemplo de `DataFrame` para ver esto en acción en el próximo ejercicio.\n"
]
},
{
@ -1454,9 +1457,9 @@
"source": [
"> Puntos clave: \n",
"1. Eliminar valores nulos es una buena idea solo si el conjunto de datos es lo suficientemente grande. \n",
"2. Se pueden eliminar filas o columnas completas si la mayor parte de sus datos están ausentes. \n",
"2. Se pueden eliminar filas o columnas completas si la mayoría de sus datos están ausentes. \n",
"3. El método `DataFrame.dropna(axis=)` ayuda a eliminar valores nulos. El argumento `axis` indica si se deben eliminar filas o columnas. \n",
"4. También se puede usar el argumento `how`. Por defecto, está configurado como `any`. Por lo tanto, elimina solo aquellas filas/columnas que contienen algún valor nulo. Se puede configurar como `all` para especificar que eliminaremos solo aquellas filas/columnas donde todos los valores sean nulos. \n"
"4. También se puede usar el argumento `how`. Por defecto está configurado como `any`. Por lo tanto, elimina solo aquellas filas/columnas que contienen algún valor nulo. Se puede configurar como `all` para especificar que eliminaremos solo aquellas filas/columnas donde todos los valores sean nulos. \n"
]
},
{
@ -1488,7 +1491,7 @@
"id": "38kwAihWgRsG"
},
"source": [
"El parámetro `thresh` te da un control más detallado: estableces el número de valores *no nulos* que una fila o columna necesita tener para ser conservada:\n"
"El parámetro `thresh` te ofrece un control más detallado: defines la cantidad de valores *no nulos* que una fila o columna necesita tener para ser conservada:\n"
]
},
{
@ -1563,7 +1566,7 @@
"id": "fmSFnzZegRsG"
},
"source": [
"Aquí, la primera y última fila se han eliminado, porque contienen solo dos valores no nulos.\n"
"Aquí, se han eliminado la primera y la última fila, porque contienen solo dos valores no nulos.\n"
]
},
{
@ -1574,9 +1577,9 @@
"source": [
"### Rellenar valores nulos\n",
"\n",
"A veces tiene sentido completar los valores faltantes con otros que podrían ser válidos. Existen varias técnicas para rellenar valores nulos. La primera es usar Conocimiento del Dominio (conocimiento del tema en el que se basa el conjunto de datos) para aproximar de alguna manera los valores faltantes.\n",
"A veces tiene sentido completar los valores faltantes con aquellos que podrían ser válidos. Hay algunas técnicas para rellenar valores nulos. La primera es usar Conocimiento del Dominio (conocimiento del tema en el que se basa el conjunto de datos) para aproximar de alguna manera los valores faltantes.\n",
"\n",
"Podrías usar `isnull` para hacer esto directamente, pero puede ser tedioso, especialmente si tienes muchos valores que rellenar. Dado que esta es una tarea tan común en ciencia de datos, pandas proporciona `fillna`, que devuelve una copia del `Series` o `DataFrame` con los valores faltantes reemplazados por uno de tu elección. Vamos a crear otro ejemplo de `Series` para ver cómo funciona esto en la práctica.\n"
"Puedes usar `isnull` para hacer esto directamente, pero puede ser laborioso, especialmente si tienes muchos valores que rellenar. Debido a que esta es una tarea tan común en ciencia de datos, pandas proporciona `fillna`, que devuelve una copia del `Series` o `DataFrame` con los valores faltantes reemplazados por uno de tu elección. Vamos a crear otro ejemplo de `Series` para ver cómo funciona esto en la práctica.\n"
]
},
{
@ -1585,12 +1588,12 @@
"id": "CE8S7louLezV"
},
"source": [
"### Datos Categóricos (No numéricos)\n",
"### Datos categóricos (no numéricos)\n",
"Primero, consideremos los datos no numéricos. En los conjuntos de datos, tenemos columnas con datos categóricos. Por ejemplo, Género, Verdadero o Falso, etc.\n",
"\n",
"En la mayoría de estos casos, reemplazamos los valores faltantes con la `moda` de la columna. Supongamos que tenemos 100 puntos de datos, 90 han respondido Verdadero, 8 han respondido Falso y 2 no han respondido. Entonces, podemos completar los 2 con Verdadero, considerando toda la columna.\n",
"En la mayoría de estos casos, reemplazamos los valores faltantes con la `moda` de la columna. Supongamos que tenemos 100 puntos de datos, de los cuales 90 han indicado Verdadero, 8 han indicado Falso y 2 no han respondido. Entonces, podemos completar los 2 con Verdadero, considerando toda la columna.\n",
"\n",
"Nuevamente, aquí podemos usar conocimiento del dominio. Consideremos un ejemplo de cómo completar con la moda.\n"
"Nuevamente, aquí podemos usar conocimiento del dominio. Veamos un ejemplo de cómo completar con la moda.\n"
]
},
{
@ -1695,7 +1698,9 @@
"metadata": {
"id": "MLAoMQOfNPlA"
},
"source": []
"source": [
"Ahora, primero encontremos la moda antes de llenar el valor `None` con la moda.\n"
]
},
{
"cell_type": "code",
@ -1730,7 +1735,9 @@
"metadata": {
"id": "6iNz_zG_OKrx"
},
"source": []
"source": [
"Entonces, reemplazaremos None con True\n"
]
},
{
"cell_type": "code",
@ -1850,14 +1857,14 @@
},
"source": [
"### Datos Numéricos\n",
"Ahora, pasando a los datos numéricos. Aquí, tenemos dos formas comunes de reemplazar valores faltantes:\n",
"Ahora, pasando a los datos numéricos. Aquí tenemos dos formas comunes de reemplazar valores faltantes:\n",
"\n",
"1. Reemplazar con la mediana de la fila \n",
"2. Reemplazar con el promedio de la fila \n",
"\n",
"Reemplazamos con la mediana en caso de datos sesgados con valores atípicos. Esto se debe a que la mediana es robusta frente a los valores atípicos.\n",
"Reemplazamos con la mediana en caso de datos sesgados con valores atípicos. Esto se debe a que la mediana es resistente a los valores atípicos.\n",
"\n",
"Cuando los datos están normalizados, podemos usar el promedio, ya que en ese caso, el promedio y la mediana estarían bastante cerca.\n",
"Cuando los datos están normalizados, podemos usar el promedio, ya que en ese caso, el promedio y la mediana serían bastante cercanos.\n",
"\n",
"Primero, tomemos una columna que esté distribuida normalmente y rellenemos el valor faltante con el promedio de la columna.\n"
]
@ -1999,7 +2006,9 @@
"metadata": {
"id": "oBSRGxKRS39K"
},
"source": []
"source": [
"Rellenar con la media\n"
]
},
{
"cell_type": "code",
@ -2108,7 +2117,7 @@
"id": "jIvF13a1i00Z"
},
"source": [
"Ahora intentemos con otro dataframe, y esta vez reemplazaremos los valores None con la mediana de la columna.\n"
"Ahora intentemos otro dataframe, y esta vez reemplazaremos los valores None con la mediana de la columna.\n"
]
},
{
@ -2248,7 +2257,9 @@
"metadata": {
"id": "z9PLF75Jj_1s"
},
"source": []
"source": [
"Rellenar con la mediana\n"
]
},
{
"cell_type": "code",
@ -2432,10 +2443,10 @@
},
"source": [
"> Puntos clave:\n",
"1. Completar los valores faltantes debe hacerse cuando hay poca información o cuando existe una estrategia para llenar los datos faltantes.\n",
"2. El conocimiento del dominio puede utilizarse para completar los valores faltantes aproximándolos.\n",
"3. Para datos categóricos, generalmente, los valores faltantes se sustituyen con la moda de la columna.\n",
"4. Para datos numéricos, los valores faltantes suelen completarse con la media (para conjuntos de datos normalizados) o la mediana de las columnas.\n"
"1. Completar los valores faltantes debe hacerse cuando hay poca información o existe una estrategia para llenar los datos faltantes.\n",
"2. El conocimiento del dominio puede utilizarse para aproximar y completar los valores faltantes.\n",
"3. En el caso de datos categóricos, generalmente los valores faltantes se sustituyen por la moda de la columna.\n",
"4. Para datos numéricos, los valores faltantes suelen completarse con la media (en conjuntos de datos normalizados) o la mediana de las columnas.\n"
]
},
{
@ -2465,7 +2476,9 @@
"metadata": {
"id": "kq3hw1kLgRsI"
},
"source": []
"source": [
"Puedes **rellenar hacia adelante** los valores nulos, lo que significa usar el último valor válido para llenar un nulo:\n"
]
},
{
"cell_type": "code",
@ -2720,7 +2733,7 @@
"id": "ZeMc-I1EgRsI"
},
"source": [
"Ten en cuenta que cuando no se dispone de un valor previo para completar hacia adelante, el valor nulo permanece.\n"
"Nota que cuando no se dispone de un valor previo para completar hacia adelante, el valor nulo permanece.\n"
]
},
{
@ -2753,7 +2766,7 @@
"id": "YHgy0lIrgRsJ"
},
"source": [
"Puedes ser creativo con cómo usas `fillna`. Por ejemplo, veamos nuevamente `example4`, pero esta vez llenemos los valores faltantes con el promedio de todos los valores en el `DataFrame`:\n"
"Puedes ser creativo con el uso de `fillna`. Por ejemplo, veamos nuevamente `example4`, pero esta vez llenemos los valores faltantes con el promedio de todos los valores en el `DataFrame`:\n"
]
},
{
@ -2844,9 +2857,9 @@
"id": "zpMvCkLSgRsJ"
},
"source": [
"Ten en cuenta que la columna 3 aún no tiene valores: la dirección predeterminada es completar los valores fila por fila.\n",
"Observa que la columna 3 sigue sin valores: la dirección predeterminada es llenar los valores fila por fila.\n",
"\n",
"> **Conclusión:** Hay múltiples maneras de tratar los valores faltantes en tus conjuntos de datos. La estrategia específica que utilices (eliminarlos, reemplazarlos, o incluso cómo los reemplazas) debe estar dictada por las particularidades de esos datos. Desarrollarás un mejor sentido de cómo manejar los valores faltantes cuanto más trabajes e interactúes con conjuntos de datos.\n"
"> **Conclusión:** Hay múltiples formas de tratar los valores faltantes en tus conjuntos de datos. La estrategia específica que utilices (eliminarlos, reemplazarlos, o incluso cómo los reemplazas) debe estar dictada por las particularidades de esos datos. Desarrollarás un mejor sentido de cómo manejar los valores faltantes cuanto más trabajes e interactúes con conjuntos de datos.\n"
]
},
{
@ -2870,7 +2883,7 @@
"source": [
"**CODIFICACIÓN DE ETIQUETAS**\n",
"\n",
"La codificación de etiquetas consiste básicamente en convertir cada categoría en un número. Por ejemplo, supongamos que tenemos un conjunto de datos de pasajeros de aerolíneas y hay una columna que contiene su clase entre las siguientes ['clase ejecutiva', 'clase económica', 'primera clase']. Si se realiza la codificación de etiquetas en esto, se transformaría en [0,1,2]. Veamos un ejemplo mediante código. Como estaremos aprendiendo `scikit-learn` en los próximos cuadernos, no lo utilizaremos aquí.\n"
"La codificación de etiquetas consiste básicamente en convertir cada categoría en un número. Por ejemplo, supongamos que tenemos un conjunto de datos de pasajeros de aerolíneas y hay una columna que contiene su clase entre las siguientes ['clase ejecutiva', 'clase económica', 'primera clase']. Si se realiza la codificación de etiquetas en esto, se transformaría en [0,1,2]. Veamos un ejemplo con código. Como estaremos aprendiendo `scikit-learn` en los próximos cuadernos, no lo utilizaremos aquí.\n"
]
},
{
@ -2978,7 +2991,7 @@
"id": "IDHnkwTYov-h"
},
"source": [
"Para realizar la codificación de etiquetas en la primera columna, primero debemos describir un mapeo de cada clase a un número, antes de reemplazar\n"
"Para realizar la codificación de etiquetas en la primera columna, primero debemos describir un mapeo de cada clase a un número, antes de reemplazar.\n"
]
},
{
@ -3080,8 +3093,8 @@
"id": "ftnF-TyapOPt"
},
"source": [
"Como podemos ver, el resultado coincide con lo que esperábamos. Entonces, ¿cuándo usamos la codificación de etiquetas? La codificación de etiquetas se utiliza en uno o ambos de los siguientes casos:\n",
"1. Cuando el número de categorías es grande\n",
"Como podemos observar, el resultado coincide con lo que esperábamos. Entonces, ¿cuándo usamos la codificación de etiquetas? La codificación de etiquetas se utiliza en uno o ambos de los siguientes casos:\n",
"1. Cuando el número de categorías es grande.\n",
"2. Cuando las categorías tienen un orden.\n"
]
},
@ -3091,11 +3104,11 @@
"id": "eQPAPVwsqWT7"
},
"source": [
"**CODIFICACIÓN ONE HOT**\n",
"**ONE HOT ENCODING**\n",
"\n",
"Otro tipo de codificación es la Codificación One Hot. En este tipo de codificación, cada categoría de la columna se agrega como una columna separada y cada punto de datos recibirá un 0 o un 1 dependiendo de si contiene esa categoría. Por lo tanto, si hay n categorías diferentes, se añadirán n columnas al dataframe.\n",
"Otro tipo de codificación es One Hot Encoding. En este tipo de codificación, cada categoría de la columna se agrega como una columna separada y cada dato recibirá un 0 o un 1 dependiendo de si contiene esa categoría. Por lo tanto, si hay n categorías diferentes, se añadirán n columnas al dataframe.\n",
"\n",
"Por ejemplo, tomemos el mismo ejemplo de clases de avión. Las categorías eran: ['business class', 'economy class', 'first class']. Entonces, si realizamos la codificación one hot, se agregarán las siguientes tres columnas al conjunto de datos: ['class_business class', 'class_economy class', 'class_first class'].\n"
"Por ejemplo, tomemos el mismo ejemplo de clases de avión. Las categorías eran: ['business class', 'economy class', 'first class']. Entonces, si realizamos One Hot Encoding, se agregarán las siguientes tres columnas al conjunto de datos: ['class_business class', 'class_economy class', 'class_first class'].\n"
]
},
{
@ -3328,7 +3341,7 @@
"id": "_zXRLOjXujdA"
},
"source": [
"Cada columna codificada en caliente contiene 0 o 1, lo que especifica si esa categoría existe para ese punto de datos.\n"
"Cada columna codificada en formato one-hot contiene 0 o 1, lo que especifica si esa categoría existe para ese punto de datos.\n"
]
},
{
@ -3349,9 +3362,9 @@
"id": "XnUmci_4uvyu"
},
"source": [
"> Puntos clave:\n",
"1. La codificación se utiliza para convertir datos no numéricos en datos numéricos.\n",
"2. Existen dos tipos de codificación: Codificación de etiquetas (Label encoding) y Codificación One Hot (One Hot encoding), ambas pueden realizarse según las necesidades del conjunto de datos.\n"
"> Puntos clave:\n",
"1. La codificación se realiza para convertir datos no numéricos en datos numéricos.\n",
"2. Hay dos tipos de codificación: codificación de etiquetas y codificación One Hot, ambas pueden realizarse según las necesidades del conjunto de datos.\n"
]
},
{
@ -3362,7 +3375,7 @@
"source": [
"## Eliminando datos duplicados\n",
"\n",
"> **Objetivo de aprendizaje:** Al final de esta subsección, deberías sentirte cómodo identificando y eliminando valores duplicados de DataFrames.\n",
"> **Objetivo de aprendizaje:** Al final de esta subsección, deberías sentirte cómodo identificando y eliminando valores duplicados de los DataFrames.\n",
"\n",
"Además de los datos faltantes, a menudo encontrarás datos duplicados en conjuntos de datos del mundo real. Afortunadamente, pandas ofrece una forma sencilla de detectar y eliminar entradas duplicadas.\n"
]
@ -3375,7 +3388,7 @@
"source": [
"### Identificando duplicados: `duplicated`\n",
"\n",
"Puedes identificar fácilmente valores duplicados utilizando el método `duplicated` en pandas, el cual devuelve una máscara booleana que indica si una entrada en un `DataFrame` es un duplicado de una anterior. Vamos a crear otro ejemplo de `DataFrame` para ver esto en acción.\n"
"Puedes identificar fácilmente valores duplicados utilizando el método `duplicated` en pandas, que devuelve una máscara booleana indicando si un registro en un `DataFrame` es un duplicado de uno anterior. Vamos a crear otro ejemplo de `DataFrame` para ver esto en acción.\n"
]
},
{
@ -3664,7 +3677,525 @@
"metadata": {
"id": "GvX4og1EgRsL"
},
"source": []
"source": [
"> **Conclusión:** Eliminar datos duplicados es una parte esencial de casi todos los proyectos de ciencia de datos. Los datos duplicados pueden alterar los resultados de tus análisis y proporcionarte resultados inexactos.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Verificación de calidad de datos en el mundo real\n",
"\n",
"> **Objetivo de aprendizaje:** Al finalizar esta sección, deberías sentirte cómodo detectando y corrigiendo problemas comunes de calidad de datos en el mundo real, incluyendo valores categóricos inconsistentes, valores numéricos anormales (valores atípicos) y entidades duplicadas con variaciones.\n",
"\n",
"Aunque los valores faltantes y los duplicados exactos son problemas comunes, los conjuntos de datos del mundo real suelen contener problemas más sutiles:\n",
"\n",
"1. **Valores categóricos inconsistentes**: La misma categoría escrita de manera diferente (por ejemplo, \"USA\", \"U.S.A\", \"United States\").\n",
"2. **Valores numéricos anormales**: Valores extremos que indican errores de entrada de datos (por ejemplo, edad = 999).\n",
"3. **Filas casi duplicadas**: Registros que representan la misma entidad con ligeras variaciones.\n",
"\n",
"Exploremos técnicas para detectar y manejar estos problemas.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Creando un Conjunto de Datos \"Sucio\" de Ejemplo\n",
"\n",
"Primero, vamos a crear un conjunto de datos de ejemplo que contenga los tipos de problemas que comúnmente encontramos en datos del mundo real:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np\n",
"\n",
"# Create a sample dataset with quality issues\n",
"Para casos más complejos, podemos usar la coincidencia de cadenas difusa con la biblioteca `rapidfuzz` para detectar automáticamente cadenas similares:\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"try:\n",
" from rapidfuzz import process, fuzz\n",
"except ImportError:\n",
" print(\"rapidfuzz is not installed. Please install it with 'pip install rapidfuzz' to use fuzzy matching.\")\n",
"Observa que nuestro conjunto de datos tiene múltiples entradas para \"John Smith\" con valores ligeramente diferentes. Identifiquemos posibles duplicados basándonos en la similitud de nombres.\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# First, let's look at exact name matches (ignoring extra whitespace)\n",
"1. **Categorías inconsistentes** son comunes en datos del mundo real. Siempre revisa los valores únicos y estandarízalos utilizando mapeos o coincidencias difusas.\n",
"\n",
"2. **Valores atípicos** pueden afectar significativamente tu análisis. Usa conocimiento del dominio combinado con métodos estadísticos (IQR, puntuación Z) para detectarlos.\n",
"\n",
"3. **Casi duplicados** son más difíciles de detectar que los duplicados exactos. Considera usar coincidencias difusas y normalizar los datos (convertir a minúsculas, eliminar espacios) para identificarlos.\n",
"\n",
"4. **La limpieza de datos es iterativa**. Es posible que necesites aplicar múltiples técnicas y revisar los resultados antes de finalizar tu conjunto de datos limpio.\n",
"\n",
"5. **Documenta tus decisiones**. Lleva un registro de los pasos de limpieza que aplicaste y por qué, ya que esto es importante para la reproducibilidad y la transparencia.\n",
"\n",
"> **Mejor práctica:** Siempre conserva una copia de tus datos originales \"sucios\". Nunca sobrescribas tus archivos de datos fuente; crea versiones limpias con convenciones de nombres claras como `data_cleaned.csv`.\n"