{
"cells": [
{
"cell_type": "markdown",
"id": "132f0abc",
"metadata": {},
"source": [
"# Tipos de datos\n",
"\n",
"Lo primero que tenemos que tener en cuenta es que los datos se clasifican en diversos tipos, los cuales determinan lo que podemos hacer con ellos, o mejor, sus escalas de medición.\n",
"\n",
"## Tipos de datos básicos en Python\n",
"\n",
"Los tipos de datos básicos en Python son:\n",
"\n",
"- `int`: números enteros\n",
"- `float`: números decimales\n",
"- `bool`: valores lógicos (verdadero o falso)\n",
"- `str`: cadenas de texto (cadenas de caracteres)\n",
"- `list`: listas (arrays)\n",
"- `dict`: diccionarios (objetos con claves y valores)\n",
"- `tuple`: tuplas (arrays de elementos que no se pueden modificar)\n",
"\n",
"Un mismo conjunto de datos puede tener varios tipos de datos, por ejemplo:"
]
},
{
"cell_type": "code",
"execution_count": 1,
"id": "c83e7d7a",
"metadata": {
"tags": [
"remove-cell"
]
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Requirement already satisfied: pandas in /Users/jairoantonio/opt/anaconda3/lib/python3.9/site-packages (1.3.4)\r\n",
"Requirement already satisfied: python-dateutil>=2.7.3 in /Users/jairoantonio/opt/anaconda3/lib/python3.9/site-packages (from pandas) (2.8.2)\r\n",
"Requirement already satisfied: pytz>=2017.3 in /Users/jairoantonio/opt/anaconda3/lib/python3.9/site-packages (from pandas) (2021.3)\r\n",
"Requirement already satisfied: numpy>=1.17.3 in /Users/jairoantonio/opt/anaconda3/lib/python3.9/site-packages (from pandas) (1.20.3)\r\n",
"Requirement already satisfied: six>=1.5 in /Users/jairoantonio/opt/anaconda3/lib/python3.9/site-packages (from python-dateutil>=2.7.3->pandas) (1.16.0)\r\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"\r\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m A new release of pip available: \u001b[0m\u001b[31;49m22.2.2\u001b[0m\u001b[39;49m -> \u001b[0m\u001b[32;49m22.3\u001b[0m\r\n",
"\u001b[1m[\u001b[0m\u001b[34;49mnotice\u001b[0m\u001b[1;39;49m]\u001b[0m\u001b[39;49m To update, run: \u001b[0m\u001b[32;49mpip install --upgrade pip\u001b[0m\r\n"
]
}
],
"source": [
"!pip install pandas"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "6df95eba",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Nombre | \n",
" Edad | \n",
" Registro | \n",
" Promedio | \n",
" Origen | \n",
" Calificaciones | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" Andrea | \n",
" 34 | \n",
" True | \n",
" 9.5 | \n",
" {'Ciudad': 'Ciudad de México', 'Estado': 'CDMX'} | \n",
" (9, 8, 10) | \n",
"
\n",
" \n",
" 1 | \n",
" Berenice | \n",
" 51 | \n",
" False | \n",
" 8.5 | \n",
" {'Ciudad': 'Guadalajara', 'Estado': 'Jalisco'} | \n",
" (8, 7, 9) | \n",
"
\n",
" \n",
" 2 | \n",
" Carlos | \n",
" 26 | \n",
" True | \n",
" 10.0 | \n",
" {'Ciudad': 'Toluca', 'Estado': 'Estado de Méxi... | \n",
" (7, 6, 8) | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Nombre Edad Registro Promedio \\\n",
"0 Andrea 34 True 9.5 \n",
"1 Berenice 51 False 8.5 \n",
"2 Carlos 26 True 10.0 \n",
"\n",
" Origen Calificaciones \n",
"0 {'Ciudad': 'Ciudad de México', 'Estado': 'CDMX'} (9, 8, 10) \n",
"1 {'Ciudad': 'Guadalajara', 'Estado': 'Jalisco'} (8, 7, 9) \n",
"2 {'Ciudad': 'Toluca', 'Estado': 'Estado de Méxi... (7, 6, 8) "
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"import pandas as pd\n",
"\n",
"ejemplo1 = pd.DataFrame(\n",
" {\"Nombre\": [\"Andrea\", \"Berenice\", \"Carlos\"], # tipo de datos string\n",
" \"Edad\": [34, 51, 26], # tipo de datos int\n",
" \"Registro\": [True, False, True], # tipo de datos bool\n",
" \"Promedio\": [9.5, 8.5, 10], # tipo de datos float\n",
" \"Origen\": [\n",
" {\"Ciudad\": \"Ciudad de México\", \"Estado\": \"CDMX\"}, \n",
" {\"Ciudad\": \"Guadalajara\", \"Estado\": \"Jalisco\"}, \n",
" {\"Ciudad\": \"Toluca\", \"Estado\": \"Estado de México\"}\n",
" ], # tipo de datos dict \n",
" \"Calificaciones\": [(9, 8, 10), (8, 7, 9), (7, 6, 8)] # tipo de datos tuple\n",
" })\n",
"\n",
"ejemplo1"
]
},
{
"cell_type": "markdown",
"id": "d6c4c26f",
"metadata": {},
"source": [
"Como verás, el conjunto de datos permite cualquier tipo incorporado en sus columnas. La coherencia de los datos depende de las restricciones que hayan sido impuestas para la creación de los datos. Por ejemplo, si los datos fueron incorporados a través de un modelo de base de datos los tipos de datos seguramente estarán claramente definidos por la arquitectura de la base; pero si los datos fueron volcados manualmente en una hoja de cálculo,pueden ser ambiguos.\n",
"\n",
"## ¿Por qué es relevante el tipo de datos?\n",
"\n",
"Para aclarar más lo anterior. Supongamos que nos encontramos con el siguiente conjunto de datos:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "9a438594",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" | \n",
" Nombre | \n",
" Edad | \n",
"
\n",
" \n",
" \n",
" \n",
" 0 | \n",
" Andrea | \n",
" 34 | \n",
"
\n",
" \n",
" 1 | \n",
" Berenice | \n",
" 51 | \n",
"
\n",
" \n",
" 2 | \n",
" Carlos | \n",
" 26 | \n",
"
\n",
" \n",
"
\n",
"
"
],
"text/plain": [
" Nombre Edad\n",
"0 Andrea 34\n",
"1 Berenice 51\n",
"2 Carlos 26"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ejemplo2 = pd.DataFrame(\n",
" {\"Nombre\": [\"Andrea\", \"Berenice\", \"Carlos\"], \n",
" \"Edad\": [\"34\", \"51\", \"26\"]})\n",
"\n",
"ejemplo2"
]
},
{
"cell_type": "markdown",
"id": "3150302f",
"metadata": {},
"source": [
"A simple vista, los datos parecen adecuados y no hay ningún error evidente. El problema es que no podríamos procesarlos de manera adecuada. Si quisiera hacer un promedio de la edad de los alumnos tendría el siguiente error:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "4c1ce65d",
"metadata": {},
"outputs": [
{
"ename": "TypeError",
"evalue": "unsupported operand type(s) for +: 'int' and 'str'",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m/var/folders/6z/cjmzygfj49d6yzn_qgny7hgr0000gp/T/ipykernel_99094/2923977663.py\u001b[0m in \u001b[0;36m\u001b[0;34m\u001b[0m\n\u001b[0;32m----> 1\u001b[0;31m \u001b[0mpromedio\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mejemplo2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mEdad\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m/\u001b[0m\u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mejemplo2\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mEdad\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;31mTypeError\u001b[0m: unsupported operand type(s) for +: 'int' and 'str'"
]
}
],
"source": [
"promedio = sum(ejemplo2.Edad)/len(ejemplo2.Edad)"
]
},
{
"cell_type": "markdown",
"id": "8d058e4b",
"metadata": {},
"source": [
"Este es un error de tipo (`TypeError`) que indica que estamos intentando ejecutar una operación incorrecta (sumar y dividir) con un tipo de dato incompatible.\n",
"\n",
"Cuando trabajamos con `pandas` esto puede conllevar otros problemas como el siguiente:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "ba1bc741",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"115042.0"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ejemplo2[\"Edad\"].mean()"
]
},
{
"cell_type": "markdown",
"id": "b4dfa713",
"metadata": {},
"source": [
"Sabemos que el promedio de 34, 51 y 26 no puede ser 115,042; no obstante, `pandas` realiza una operación con nuestros datos y nos devuelve el promedio incorrecto. En este ejemplo sabemos exactamente el valor que debe devolver el promedio, por lo que inmediatamente entendemos que debemos corregir nuestra operación para obtener el resultado correcto, pero en grandes conjuntos de datos podría llevar a un error.\n",
"\n",
"Por esta razón, debemos asegurarnos de que los datos que se procesan son compatibles para realizar las mediciones que se requieran. En la tercera parte del curso veremos como hacer esto, que es básicamente lo que les muestro a continuación:"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "b215f6d0",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"37.0"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ejemplo2[\"Edad\"] = ejemplo2[\"Edad\"].astype(int)\n",
"ejemplo2[\"Edad\"].mean()"
]
},
{
"cell_type": "markdown",
"id": "26ce6f11",
"metadata": {},
"source": [
"En este caso, el promedio ya se puede calcular de manera correcta porque el tipo de dato es adecuado: `int`."
]
}
],
"metadata": {
"jupytext": {
"cell_metadata_filter": "-all",
"formats": "md:myst",
"text_representation": {
"extension": ".md",
"format_name": "myst",
"format_version": 0.13,
"jupytext_version": "1.14.1"
}
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.7"
},
"source_map": [
14,
34,
39,
56,
64,
70,
74,
76,
82,
84,
90,
93
]
},
"nbformat": 4,
"nbformat_minor": 5
}