{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Procesamiento de datos con SQLite3 --- 12:13 min\n",
"===\n",
"\n",
"* 12:13 min | Última modificación: Octubre 14, 2021 | [YouTube](https://youtu.be/8LvpTsN_h1U)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Este tutorial esta basado en https://es.hortonworks.com/tutorial/how-to-process-data-with-apache-hive/\n",
"\n",
"El objetivo de este tutorial es implemetar consultas en SQLite3 para analizar, procesar y filtrar datos usando lenguaje SQL estándar.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Fuentes de datos\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Los archivos usados en este tutorial se encuentran almacenados en la carpeta actual"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"/tmp/bonus.csv\n",
"/tmp/clients.csv\n",
"/tmp/clients_a.csv\n",
"/tmp/clients_b.csv\n",
"/tmp/data.csv\n",
"/tmp/data_1.csv\n",
"/tmp/data_2.csv\n",
"/tmp/dataset_1.csv\n",
"/tmp/dataset_2.csv\n",
"/tmp/drivers.csv\n",
"/tmp/lines.csv\n",
"/tmp/sales.csv\n",
"/tmp/specific-columns.csv\n",
"/tmp/summary.csv\n",
"/tmp/timesheet.csv\n",
"/tmp/truck_event_text_partition.csv\n"
]
}
],
"source": [
"filenames = [\n",
" \"drivers.csv\",\n",
" \"timesheet.csv\",\n",
" \"truck_event_text_partition.csv\",\n",
"]\n",
"\n",
"url = \"https://raw.githubusercontent.com/jdvelasq/datalabs/master/datasets/drivers/\"\n",
"\n",
"for filename in filenames:\n",
" !wget --quiet {url + filename} -P /tmp/\n",
"\n",
"!ls -1 /tmp/*.csv"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Preparación\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"#\n",
"# Apertura de la conexión\n",
"#\n",
"import sqlite3\n",
"\n",
"conn = sqlite3.connect(\":memory:\") ## aca se indica el nombre de la db.\n",
"cur = conn.cursor()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"El contenido de un archivo puede ser visualizado parcialmente usando el comando `tail`. Se usa para realizar una inspección rápida del contenido de los archivos."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"39,David Kaiser,967706052,9185 At Street,Y,hours\n",
"40,Nicolas Maillard,208510217,1027 Quis Rd.,Y,hours\n",
"41,Greg Phillips,308103116,P.O. Box 847- 5961 Arcu. Road,Y,hours\n",
"42,Randy Gelhausen,853302254,145-4200 In- Avenue,Y,hours\n",
"43,Dave Patton,977706052,3028 A- St.,Y,hours"
]
}
],
"source": [
"#\n",
"# Se imprime el final del archivo drivers\n",
"#\n",
"!tail -n 5 /tmp/drivers.csv"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"43,48,52,2517\n",
"43,49,56,2743\n",
"43,50,59,2665\n",
"43,51,58,2593\n",
"43,52,48,2764"
]
}
],
"source": [
"!tail -n 5 /tmp/timesheet.csv"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Creación y carga de datos de datos para la tabla `drivers` usando pandas\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"En el siguiente código, los datos son cargados con pandas, para luego crear la tabla de la base de datos a partir del DataFrame. Note que no hay que crear la tabla primero en la base de datos, sino que pandas la crea directamente."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"\n",
"drivers = pd.read_csv(\n",
" \"/tmp/drivers.csv\",\n",
" sep=\",\",\n",
" thousands=None,\n",
" decimal=\".\",\n",
" encoding=\"latin-1\",\n",
")\n",
"\n",
"drivers.columns = [col.replace('-', '_') for col in drivers.columns]\n",
"\n",
"drivers.to_sql(\n",
" name=\"drivers\",\n",
" con=conn,\n",
" if_exists=\"replace\", # {‘fail’, ‘replace’, ‘append’}\n",
")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se obtiene el primer registro de la tabla para realizar una inspección rápida de los datos y verificar que los datos fueron cargados correctamente."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"
\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" driverId \n",
" name \n",
" ssn \n",
" location \n",
" certified \n",
" wage_plan \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 10 \n",
" George Vetticaden \n",
" 621011971 \n",
" 244-4532 Nulla Rd. \n",
" N \n",
" miles \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" driverId name ssn location certified \\\n",
"0 10 George Vetticaden 621011971 244-4532 Nulla Rd. N \n",
"\n",
" wage_plan \n",
"0 miles "
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"drivers[0:1]"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(0, 10, 'George Vetticaden', 621011971, '244-4532 Nulla Rd.', 'N', 'miles')]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cur.execute(\"SELECT * FROM drivers LIMIT 1;\").fetchall()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Creación y carga de datos de la tabla `timesheet`\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Se procede a cargar los datos para el archivo `time_sheet`."
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"timesheet = pd.read_csv(\n",
" \"/tmp/timesheet.csv\", sep=\",\", thousands=None, decimal=\".\", encoding=\"latin-1\"\n",
")\n",
"\n",
"timesheet.columns = [col.replace('-', '_') for col in timesheet.columns]\n",
"\n",
"timesheet.to_sql(name=\"timesheet\", con=conn, if_exists=\"replace\")"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"
\n",
" \n",
" \n",
" \n",
" driverId \n",
" week \n",
" hours_logged \n",
" miles_logged \n",
" \n",
" \n",
" \n",
" \n",
" 0 \n",
" 10 \n",
" 1 \n",
" 70 \n",
" 3300 \n",
" \n",
" \n",
"
\n",
"
"
],
"text/plain": [
" driverId week hours_logged miles_logged\n",
"0 10 1 70 3300"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"timesheet[0:1]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(10, 1, 70, 3300)]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cur.execute(\n",
" \"SELECT driverId, week, hours_logged, miles_logged FROM timesheet LIMIT 1;\"\n",
").fetchall()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cantidad de horas y millas de cada conductor por año.\n",
"----\n",
"\n",
"En la siguiente consulta se desea obtener para cada conductor la cantidad de horas y millas por año."
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(10, 3232, 147150),\n",
" (11, 3642, 179300),\n",
" (12, 2639, 135962),\n",
" (13, 2727, 134126),\n",
" (14, 2781, 136624),\n",
" (15, 2734, 138750),\n",
" (16, 2746, 137205),\n",
" (17, 2701, 135992),\n",
" (18, 2654, 137834),\n",
" (19, 2738, 137968),\n",
" (20, 2644, 134564),\n",
" (21, 2751, 138719),\n",
" (22, 2733, 137550),\n",
" (23, 2750, 137980),\n",
" (24, 2647, 134461),\n",
" (25, 2723, 139180),\n",
" (26, 2730, 137530),\n",
" (27, 2771, 137922),\n",
" (28, 2723, 137469),\n",
" (29, 2760, 138255),\n",
" (30, 2773, 137473),\n",
" (31, 2704, 137057),\n",
" (32, 2736, 137422),\n",
" (33, 2759, 139285),\n",
" (34, 2811, 137728),\n",
" (35, 2728, 138727),\n",
" (36, 2795, 138025),\n",
" (37, 2694, 137223),\n",
" (38, 2760, 137464),\n",
" (39, 2745, 138788),\n",
" (40, 2700, 136931),\n",
" (41, 2723, 138407),\n",
" (42, 2697, 136673),\n",
" (43, 2750, 136993)]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cur.execute(\n",
" \"\"\"\n",
"SELECT \n",
" driverId, \n",
" sum(hours_logged), \n",
" sum(miles_logged) \n",
"FROM \n",
" timesheet \n",
"GROUP BY \n",
" driverId;\n",
"\"\"\"\n",
").fetchall()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Subconsultas\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(0, 10, 1, 70, 3300),\n",
" (1, 10, 2, 70, 3300),\n",
" (2, 10, 3, 60, 2800),\n",
" (3, 10, 4, 70, 3100),\n",
" (4, 10, 5, 70, 3200),\n",
" (5, 10, 6, 70, 3300),\n",
" (6, 10, 7, 70, 3000),\n",
" (7, 10, 8, 70, 3300),\n",
" (8, 10, 9, 70, 3200),\n",
" (9, 10, 10, 50, 2500),\n",
" (10, 10, 11, 70, 2900),\n",
" (11, 10, 12, 70, 3100),\n",
" (12, 10, 13, 70, 3300),\n",
" (13, 10, 14, 70, 3300),\n",
" (14, 10, 15, 70, 3300),\n",
" (15, 10, 16, 70, 3400),\n",
" (16, 10, 17, 70, 3300),\n",
" (17, 10, 18, 70, 3300),\n",
" (18, 10, 19, 70, 3300),\n",
" (19, 10, 20, 30, 1200),\n",
" (20, 10, 21, 50, 2500),\n",
" (21, 10, 22, 70, 3300),\n",
" (22, 10, 23, 70, 3300),\n",
" (23, 10, 24, 70, 3300),\n",
" (24, 10, 25, 70, 3300),\n",
" (25, 10, 26, 60, 2600),\n",
" (26, 10, 27, 66, 2700),\n",
" (27, 10, 28, 33, 1200),\n",
" (28, 10, 29, 70, 3300),\n",
" (29, 10, 30, 70, 3300),\n",
" (30, 10, 31, 72, 3100),\n",
" (31, 10, 32, 70, 3200),\n",
" (32, 10, 33, 70, 3300),\n",
" (33, 10, 34, 70, 3300),\n",
" (34, 10, 35, 0, 0),\n",
" (35, 10, 36, 19, 1000),\n",
" (36, 10, 37, 65, 2700),\n",
" (37, 10, 38, 70, 3300),\n",
" (38, 10, 39, 70, 3300),\n",
" (39, 10, 40, 70, 3100),\n",
" (40, 10, 41, 70, 3300),\n",
" (41, 10, 42, 70, 3100),\n",
" (42, 10, 43, 70, 3300),\n",
" (43, 10, 44, 70, 3300),\n",
" (44, 10, 45, 65, 2700),\n",
" (45, 10, 46, 57, 2300),\n",
" (46, 10, 47, 74, 3400),\n",
" (47, 10, 48, 76, 3400),\n",
" (48, 10, 49, 68, 2800),\n",
" (49, 10, 50, 72, 2900),\n",
" (50, 10, 51, 5, 150),\n",
" (51, 10, 52, 0, 0)]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#\n",
"# Selecciona todos los registros de la tabla timesheet\n",
"# que tienen el driverId igual al menor driverId de la\n",
"# tabla drivers.\n",
"#\n",
"cur.execute(\n",
" \"\"\"\n",
"SELECT \n",
" *\n",
"FROM\n",
" timesheet\n",
"WHERE\n",
" driverId = (SELECT min(driverId) FROM drivers);\n",
"\"\"\"\n",
").fetchall()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Consulta para unir las tablas\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"El paso final consiste en crear una consulta que agregue el nombre del conductor de la tabla `drivers` con la cantidad de horas y millas por año."
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(10, 'George Vetticaden', 3232, 147150),\n",
" (11, 'Jamie Engesser', 3642, 179300),\n",
" (12, 'Paul Coddin', 2639, 135962),\n",
" (13, 'Joe Niemiec', 2727, 134126),\n",
" (14, 'Adis Cesir', 2781, 136624),\n",
" (15, 'Rohit Bakshi', 2734, 138750),\n",
" (16, 'Tom McCuch', 2746, 137205),\n",
" (17, 'Eric Mizell', 2701, 135992),\n",
" (18, 'Grant Liu', 2654, 137834),\n",
" (19, 'Ajay Singh', 2738, 137968),\n",
" (20, 'Chris Harris', 2644, 134564),\n",
" (21, 'Jeff Markham', 2751, 138719),\n",
" (22, 'Nadeem Asghar', 2733, 137550),\n",
" (23, 'Adam Diaz', 2750, 137980),\n",
" (24, 'Don Hilborn', 2647, 134461),\n",
" (25, 'Jean-Philippe Playe', 2723, 139180),\n",
" (26, 'Michael Aube', 2730, 137530),\n",
" (27, 'Mark Lochbihler', 2771, 137922),\n",
" (28, 'Olivier Renault', 2723, 137469),\n",
" (29, 'Teddy Choi', 2760, 138255),\n",
" (30, 'Dan Rice', 2773, 137473),\n",
" (31, 'Rommel Garcia', 2704, 137057),\n",
" (32, 'Ryan Templeton', 2736, 137422),\n",
" (33, 'Sridhara Sabbella', 2759, 139285),\n",
" (34, 'Frank Romano', 2811, 137728),\n",
" (35, 'Emil Siemes', 2728, 138727),\n",
" (36, 'Andrew Grande', 2795, 138025),\n",
" (37, 'Wes Floyd', 2694, 137223),\n",
" (38, 'Scott Shaw', 2760, 137464),\n",
" (39, 'David Kaiser', 2745, 138788),\n",
" (40, 'Nicolas Maillard', 2700, 136931),\n",
" (41, 'Greg Phillips', 2723, 138407),\n",
" (42, 'Randy Gelhausen', 2697, 136673),\n",
" (43, 'Dave Patton', 2750, 136993)]"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"cur.execute(\n",
" \"\"\"\n",
"SELECT \n",
" d.driverId, \n",
" d.name, \n",
" t.total_hours, \n",
" t.total_miles \n",
"FROM \n",
" drivers d\n",
"JOIN (\n",
" SELECT \n",
" driverId, \n",
" sum(hours_logged)total_hours, \n",
" sum(miles_logged)total_miles \n",
" FROM \n",
" timesheet \n",
" GROUP BY \n",
" driverId \n",
" ) t\n",
"ON \n",
" (d.driverId = t.driverId);\n",
"\"\"\"\n",
").fetchall()"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[(11, 'Jamie Engesser', 3642, 179300)]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"#\n",
"# Conductor con más horas registradas\n",
"#\n",
"cur.execute(\n",
" \"\"\"\n",
"SELECT \n",
" d.driverId, \n",
" d.name, \n",
" t.total_hours, \n",
" t.total_miles \n",
"FROM \n",
" drivers d\n",
"JOIN (\n",
" SELECT \n",
" driverId, \n",
" sum(hours_logged)total_hours, \n",
" sum(miles_logged)total_miles \n",
" FROM \n",
" timesheet \n",
" GROUP BY \n",
" driverId \n",
" ) t\n",
"ON \n",
" (d.driverId = t.driverId)\n",
"ORDER BY\n",
" t.total_hours DESC\n",
"LIMIT 1;\n",
"\"\"\"\n",
").fetchall()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Creación de un DataFrame usando una consulta\n",
"---"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"image/png": "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\n",
"text/plain": [
""
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"df = pd.read_sql(\n",
" \"\"\"\n",
"SELECT \n",
" d.driverId, \n",
" d.name, \n",
" t.total_hours, \n",
" t.total_miles \n",
"FROM \n",
" drivers d\n",
"JOIN (\n",
" SELECT \n",
" driverId, \n",
" sum(hours_logged) total_hours, \n",
" sum(miles_logged) total_miles \n",
" FROM \n",
" timesheet \n",
" GROUP BY \n",
" driverId \n",
" ) t\n",
"ON \n",
" (d.driverId = t.driverId);\n",
"\"\"\",\n",
" con=conn,\n",
")\n",
"\n",
"import matplotlib as mpl\n",
"import matplotlib.pyplot as plt\n",
"\n",
"df.plot.bar(x=\"name\", y=\"total_hours\");"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Almacenamiento de los resultados\n",
"---"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Los resultados de la consulta son cargados directamente a variable `summary` c como una lista de tuplas. El contenido de la variable es transformado para escribir un archivo de texto en formato CSV que pueda ser consultado por otras aplicaciones."
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"960"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"summary = cur.execute(\n",
" \"\"\"\n",
"SELECT \n",
" d.driverId, \n",
" d.name, \n",
" t.total_hours, \n",
" t.total_miles \n",
"FROM \n",
" drivers d\n",
"JOIN (\n",
" SELECT \n",
" driverId, \n",
" sum(hours_logged) total_hours, \n",
" sum(miles_logged) total_miles \n",
" FROM \n",
" timesheet \n",
" GROUP BY \n",
" driverId \n",
" ) t\n",
"ON \n",
" (d.driverId = t.driverId)\n",
"ORDER BY\n",
" d.name;\n",
"\"\"\"\n",
").fetchall()\n",
"\n",
"text = [[str(e) for e in row] for row in summary]\n",
"text = [\",\".join(row) for row in text]\n",
"text = \"\\n\".join(text)\n",
"open(\"/tmp/summary.csv\", \"wt\").write(text)"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"23,Adam Diaz,2750,137980\n",
"14,Adis Cesir,2781,136624\n",
"19,Ajay Singh,2738,137968\n",
"36,Andrew Grande,2795,138025\n",
"20,Chris Harris,2644,134564\n",
"30,Dan Rice,2773,137473\n",
"43,Dave Patton,2750,136993\n",
"39,David Kaiser,2745,138788\n",
"24,Don Hilborn,2647,134461\n",
"35,Emil Siemes,2728,138727\n"
]
}
],
"source": [
"!head /tmp/summary.csv"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"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.6.9"
}
},
"nbformat": 4,
"nbformat_minor": 4
}