├── Clase 1
├── 01_Introducción_y_red_de_transporte.ipynb
├── boeing-osmnx-street-networks.pdf
├── data
│ ├── USA-piedmont.graphml
│ ├── santa-monica.graphml
│ ├── scl-lascondes-network.graphml
│ └── scl-network.graphml
├── images
│ ├── paris_bldgs.png
│ └── piedmont_bldgs.png
└── img
│ ├── datagramas.png
│ ├── libro.png
│ └── wikipedia_song.png
├── Clase 2
├── 02_introducción_a_pandas-Formato-Estudiantes.ipynb
└── SalesJan2009.csv
├── Clase 3
├── 03_Groupping_&_Apply-Estudiantes.ipynb
├── grouping.png
└── grouping2.png
├── Clase 4
├── Seaborn & Matplotlib - Formato Estudiantes.ipynb
├── matplotlib.png
└── seaborn.png
├── Clase 5
├── Introducción a MatplotLib-Formato Estudiantes.ipynb
├── Ticks.png
├── axes.png
├── ejercicio1.png
├── ejercicio11.png
├── ejercicio2.png
├── figureParameters.png
├── figureParts.png
└── subplots.png
├── Clase 6
├── Clase 6 - Formato Estudiantes.ipynb
├── gqm.png
├── mini_ejercicio1.png
├── mini_ejercicio22.png
└── mini_ejercicio222.png
├── Clase 7
├── Final Clase 7 Estudiante.ipynb
├── graf1.png
├── graf2.png
├── graf3.png
├── graf4.png
├── graf5.png
├── prueba_plotly.png
├── timesData.csv
└── torpedo.png
├── Clase 8
├── Clase 8.ipynb
├── data-society-major-speeches-by-donald-trump.zip
└── data-society-twitters-about-us-airline.zip
└── README.md
/Clase 1/01_Introducción_y_red_de_transporte.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "slideshow": {
7 | "slide_type": "slide"
8 | }
9 | },
10 | "source": [
11 | "\n",
12 | " \n",
13 | "\n",
14 | " \n",
15 | "\n",
16 | "# Taller de Manejo y Visualización de Datos con Python\n",
17 | "Introducción y motivación al taller \n",
18 | "Felipe González P. \n",
19 | "felipe.gonzalezp.12@sansano.usm.cl \n",
20 | "\n",
21 | " \n",
22 | "Jueves Bloque 7-8 \n",
23 | "Campus San Joaquin\n",
24 | "\n",
25 | "\n"
26 | ]
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "metadata": {
31 | "slideshow": {
32 | "slide_type": "slide"
33 | }
34 | },
35 | "source": [
36 | "
\n",
37 | "*Data by itself is uselss. Data is only useful if you apply it* \n",
38 | "
\n",
39 | "\n",
40 | " — Todd Park.\n",
41 | "
\n",
42 | " \n"
43 | ]
44 | },
45 | {
46 | "cell_type": "markdown",
47 | "metadata": {
48 | "slideshow": {
49 | "slide_type": "slide"
50 | }
51 | },
52 | "source": [
53 | "## ¿Qué Haremos?"
54 | ]
55 | },
56 | {
57 | "cell_type": "markdown",
58 | "metadata": {
59 | "slideshow": {
60 | "slide_type": "fragment"
61 | }
62 | },
63 | "source": [
64 | "Desarrollar habilidades de análisis y visualizacion de información. Se utilizará Python con el framework Anaconda y las librerías Pandas y Matplotlib."
65 | ]
66 | },
67 | {
68 | "cell_type": "markdown",
69 | "metadata": {
70 | "slideshow": {
71 | "slide_type": "slide"
72 | }
73 | },
74 | "source": [
75 | "\n",
76 | "## Objetivos\n"
77 | ]
78 | },
79 | {
80 | "cell_type": "markdown",
81 | "metadata": {
82 | "slideshow": {
83 | "slide_type": "fragment"
84 | }
85 | },
86 | "source": [
87 | "* Extraer conjuntos de datos ( datasets ) desde la web"
88 | ]
89 | },
90 | {
91 | "cell_type": "markdown",
92 | "metadata": {
93 | "slideshow": {
94 | "slide_type": "fragment"
95 | }
96 | },
97 | "source": [
98 | "* Aplicar técnicas de limpieza de datos\n"
99 | ]
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {
104 | "slideshow": {
105 | "slide_type": "fragment"
106 | }
107 | },
108 | "source": [
109 | "* Aplicar distintas técnicas de visualización de información\n"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {
115 | "slideshow": {
116 | "slide_type": "fragment"
117 | }
118 | },
119 | "source": [
120 | "* Conocer aplicaciones de análisis y visualización de información en la industria\n"
121 | ]
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "metadata": {
126 | "slideshow": {
127 | "slide_type": "fragment"
128 | }
129 | },
130 | "source": [
131 | "* Presentar de manera oral y escrita información sobre un determinado dataset"
132 | ]
133 | },
134 | {
135 | "cell_type": "markdown",
136 | "metadata": {
137 | "slideshow": {
138 | "slide_type": "slide"
139 | }
140 | },
141 | "source": [
142 | "## Evaluación\n",
143 | " "
144 | ]
145 | },
146 | {
147 | "cell_type": "markdown",
148 | "metadata": {
149 | "slideshow": {
150 | "slide_type": "fragment"
151 | }
152 | },
153 | "source": [
154 | "### NF = 30% Asistencia + 5% Informe Preliminar + 65 % Trabajo Final ( 40 % Presentación + 60 % Informe Escrito)\n",
155 | "*Se requiere un mínimo de 80% de Asistencia para aprobar el curso.*"
156 | ]
157 | },
158 | {
159 | "cell_type": "markdown",
160 | "metadata": {
161 | "slideshow": {
162 | "slide_type": "slide"
163 | }
164 | },
165 | "source": [
166 | "## Referencias"
167 | ]
168 | },
169 | {
170 | "cell_type": "markdown",
171 | "metadata": {
172 | "slideshow": {
173 | "slide_type": "fragment"
174 | }
175 | },
176 | "source": [
177 | " \n",
178 | "
\n",
179 | "
\n",
180 | "
\n",
181 | "
Leer Libro Aquí \n",
182 | "
\n"
183 | ]
184 | },
185 | {
186 | "cell_type": "markdown",
187 | "metadata": {
188 | "slideshow": {
189 | "slide_type": "slide"
190 | }
191 | },
192 | "source": [
193 | "## Referencias"
194 | ]
195 | },
196 | {
197 | "cell_type": "markdown",
198 | "metadata": {
199 | "slideshow": {
200 | "slide_type": "fragment"
201 | }
202 | },
203 | "source": [
204 | " \n"
210 | ]
211 | },
212 | {
213 | "cell_type": "markdown",
214 | "metadata": {
215 | "slideshow": {
216 | "slide_type": "slide"
217 | }
218 | },
219 | "source": [
220 | "## Anaconda\n"
221 | ]
222 | },
223 | {
224 | "cell_type": "markdown",
225 | "metadata": {
226 | "slideshow": {
227 | "slide_type": "fragment"
228 | }
229 | },
230 | "source": [
231 | "* Dice ser: *\"The Most Popular Python Data Science Platform\"*\n",
232 | "* Herramienta freemium que soporta Python y R. \n",
233 | "* Se utiliza para procesar grandes cantidades de datos, análisis predictivo y tareas de computacionación científica. \n",
234 | "* Su objetivo es simplificar la administración y despliegue de paquetes\n",
235 | "\n",
236 | "\n",
237 | "
\n",
238 | "
Descarga Anaconda Aquí \n",
239 | " **Importante: Se utilizará Python 2.7 para el desarrollo del taller**\n",
240 | "
\n"
241 | ]
242 | },
243 | {
244 | "cell_type": "markdown",
245 | "metadata": {
246 | "slideshow": {
247 | "slide_type": "slide"
248 | }
249 | },
250 | "source": [
251 | "# Instalar Anaconda\n",
252 | "* Tutorial de Instalación de Anaconda \n",
253 | "\n",
254 | "# Ejecutar Anaconda\n",
255 | "* En linea de comandos escribir: jupyter notebook\n"
256 | ]
257 | },
258 | {
259 | "cell_type": "markdown",
260 | "metadata": {
261 | "slideshow": {
262 | "slide_type": "slide"
263 | }
264 | },
265 | "source": [
266 | " ¡COMENCEMOS! "
267 | ]
268 | },
269 | {
270 | "cell_type": "markdown",
271 | "metadata": {
272 | "slideshow": {
273 | "slide_type": "slide"
274 | }
275 | },
276 | "source": [
277 | "# OpenStreetMap y red de transporte\n",
278 | "\n",
279 | "Créditos a: Diego Caro y Eduardo Graells-Garrido del Instituto de Data Science, Ingeniería UDD.\n",
280 | "\n",
281 | "[OpenStreetMap](https://www.openstreetmap.org/) es una iniciativa colaborativa para crear el mapa editable del mundo. En otras palabras, Wikipedia es a Encyclopædia Britannica lo que OpenStreetMap es a Google Maps.\n",
282 | "\n",
283 | "En el ejercicio de hoy revisaremos cómo calcular la ruta más corta entre dos localidades utilizando información disponible en OpenStreetMap.\n",
284 | "\n",
285 | "Para procesar los datos de OpenStreetMap utilizaremos el módulo Python [OSMnx](https://github.com/gboeing/osmnx). OSMnx es desarrollado por [Geoff Boeing](https://twitter.com/gboeing). El análisis de la ruta más corta lo realizamos con el módulo [NetworkX](https://networkx.github.io/) \n",
286 | "\n"
287 | ]
288 | },
289 | {
290 | "cell_type": "markdown",
291 | "metadata": {
292 | "slideshow": {
293 | "slide_type": "slide"
294 | }
295 | },
296 | "source": [
297 | "*OSMnx lets you **download spatial geometries and construct, project, visualize, and analyze complex street networks**. It allows you to **automate the collection and computational analysis of street networks** for powerful and consistent research, transportation engineering, and urban design. OSMnx is built on top of NetworkX, matplotlib, and geopandas for rich network analytic capabilities, beautiful and simple visualizations, and fast spatial queries with R-tree.*\n",
298 | "\n",
299 | "### Documentación: http://osmnx.readthedocs.io/en/stable/osmnx.html"
300 | ]
301 | },
302 | {
303 | "cell_type": "markdown",
304 | "metadata": {
305 | "slideshow": {
306 | "slide_type": "slide"
307 | }
308 | },
309 | "source": [
310 | "Revisa el [artículo](http://geoffboeing.com/publications/osmnx-complex-street-networks/) de OSMnx: \n",
311 | "* Boeing, G. 2017. “OSMnx: New Methods for Acquiring, Constructing, Analyzing, and Visualizing Complex Street Networks.” Computers, Environment and Urban Systems. 65, 126-139. doi:10.1016/j.compenvurbsys.2017.05.004"
312 | ]
313 | },
314 | {
315 | "cell_type": "code",
316 | "execution_count": null,
317 | "metadata": {
318 | "slideshow": {
319 | "slide_type": "slide"
320 | }
321 | },
322 | "outputs": [],
323 | "source": [
324 | "import osmnx as ox\n",
325 | "import networkx as nx\n",
326 | "import matplotlib.pyplot as plt\n",
327 | "\n",
328 | "%config InlineBackend.figure_format = 'retina' # mejor resolución\n",
329 | "%matplotlib inline\n"
330 | ]
331 | },
332 | {
333 | "cell_type": "markdown",
334 | "metadata": {
335 | "slideshow": {
336 | "slide_type": "slide"
337 | }
338 | },
339 | "source": [
340 | "# Descargando Mapa\n",
341 | "La función [ox.graph_from_place(...)](http://osmnx.readthedocs.io/en/stable/osmnx.html?highlight=graph_from_place#osmnx.core.graph_from_place) descarga el mapa de una zona (comuna, región o país). Por ejemplo, el de la comuna de San Joaquín."
342 | ]
343 | },
344 | {
345 | "cell_type": "code",
346 | "execution_count": null,
347 | "metadata": {
348 | "slideshow": {
349 | "slide_type": "fragment"
350 | }
351 | },
352 | "outputs": [],
353 | "source": [
354 | "# Descargar mapa de la comuna de santiago\n",
355 | "#G = ox.graph_from_place('Santiago, Chile', network_type='drive')\n",
356 | "\n",
357 | "\n",
358 | "# Guardarlo para posterior uso :)\n",
359 | "#ox.save_graphml(G, filename='./scl-network.graphml')\n",
360 | "\n"
361 | ]
362 | },
363 | {
364 | "cell_type": "code",
365 | "execution_count": null,
366 | "metadata": {
367 | "slideshow": {
368 | "slide_type": "fragment"
369 | }
370 | },
371 | "outputs": [],
372 | "source": [
373 | "# Cargar un mapa ya guardado\n",
374 | "G = ox.load_graphml('./scl-network.graphml')\n"
375 | ]
376 | },
377 | {
378 | "cell_type": "markdown",
379 | "metadata": {
380 | "slideshow": {
381 | "slide_type": "slide"
382 | }
383 | },
384 | "source": [
385 | "La siguiente figura muestra el mapa de la comuna. Cada nodo (punto) indica alguna esquina o intersección de calles, y cada línea indica una calle."
386 | ]
387 | },
388 | {
389 | "cell_type": "code",
390 | "execution_count": null,
391 | "metadata": {
392 | "slideshow": {
393 | "slide_type": "fragment"
394 | }
395 | },
396 | "outputs": [],
397 | "source": [
398 | "ox.plot_graph(ox.project_graph(G))\n"
399 | ]
400 | },
401 | {
402 | "cell_type": "markdown",
403 | "metadata": {
404 | "slideshow": {
405 | "slide_type": "slide"
406 | }
407 | },
408 | "source": [
409 | "# ¿Cuántos metros cuadrados cubre la comuna de Santiago?"
410 | ]
411 | },
412 | {
413 | "cell_type": "code",
414 | "execution_count": null,
415 | "metadata": {
416 | "slideshow": {
417 | "slide_type": "fragment"
418 | }
419 | },
420 | "outputs": [],
421 | "source": [
422 | "G_proj = ox.project_graph(G)\n",
423 | "nodes_proj = ox.graph_to_gdfs(G_proj, edges=False)\n",
424 | "graph_area_m = nodes_proj.unary_union.convex_hull.area\n",
425 | "graph_area_m\n",
426 | "print \"La ciudad de santiago está compuesta por \"+str(graph_area_m)+\" metros cuadrados\"\n",
427 | "print \"La ciudad de santiago está compuesta por \"+str(graph_area_m/1000)+\" kilómetros cuadrados\"\n"
428 | ]
429 | },
430 | {
431 | "cell_type": "markdown",
432 | "metadata": {
433 | "slideshow": {
434 | "slide_type": "slide"
435 | }
436 | },
437 | "source": [
438 | "## Ruta más corta\n",
439 | "\n",
440 | "En este ejemplo calcularemos la ruta más corta entre el Palacio Causiño y el Palacio de la Moneda.\n",
441 | "\n",
442 | "Lo primero es traducir una dirección en una coordenada latitud/longitud. Este proceso se conoce como [Geocoding](https://en.wikipedia.org/wiki/Geocoding). Podemos utilizar Google Maps como Geocoder:\n",
443 | "* Palacio Causiño https://www.google.cl/maps/place/Palacio+Cousi%C3%B1o/@-33.4497625,-70.6600015,16z/data=!4m8!1m2!2m1!1sla+moneda!3m4!1s0x9662c508abe3af79:0xa6201fda2ff7103b!8m2!3d-33.452104!4d-70.6568125\n",
444 | "* Palacio de la Moneda\n",
445 | "https://www.google.cl/maps/place/La+Moneda+Palace/@-33.4432722,-70.6560104,17z/data=!4m8!1m2!2m1!1spalacio+la+moneda!3m4!1s0x9662c5a6fd47e465:0x5d0fa12b4d88ae82!8m2!3d-33.4429091!4d-70.6538699?hl=en\n"
446 | ]
447 | },
448 | {
449 | "cell_type": "markdown",
450 | "metadata": {
451 | "slideshow": {
452 | "slide_type": "slide"
453 | }
454 | },
455 | "source": [
456 | "Definir los puntos de origen y destino"
457 | ]
458 | },
459 | {
460 | "cell_type": "code",
461 | "execution_count": null,
462 | "metadata": {
463 | "slideshow": {
464 | "slide_type": "fragment"
465 | }
466 | },
467 | "outputs": [],
468 | "source": [
469 | "origin_point = (-33.4497625,-70.6600015) # palacio causiño\n",
470 | "destination_point = (-33.4432722,-70.6560104) # Palacio de la moneda\n"
471 | ]
472 | },
473 | {
474 | "cell_type": "markdown",
475 | "metadata": {
476 | "slideshow": {
477 | "slide_type": "slide"
478 | }
479 | },
480 | "source": [
481 | "Para encontrar la ruta entre dos localidades, es necesario encontrar el nodo (interesección) más cercano al punto de origen y destino. La función ``ox.get_nearest_node(...)`` lo hace por nosotros."
482 | ]
483 | },
484 | {
485 | "cell_type": "code",
486 | "execution_count": null,
487 | "metadata": {
488 | "slideshow": {
489 | "slide_type": "fragment"
490 | }
491 | },
492 | "outputs": [],
493 | "source": [
494 | "origin_node = ox.get_nearest_node(G, origin_point) \n",
495 | "destination_node = ox.get_nearest_node(G, destination_point)\n",
496 | "origin_node, destination_node #Lo que retorna son ID de nodos dentro del mapa"
497 | ]
498 | },
499 | {
500 | "cell_type": "markdown",
501 | "metadata": {
502 | "slideshow": {
503 | "slide_type": "slide"
504 | }
505 | },
506 | "source": [
507 | "La distancia más corta se calcula con la función ``nx.shortest_path_length(...)``. La respuesta se entrega en metros."
508 | ]
509 | },
510 | {
511 | "cell_type": "code",
512 | "execution_count": null,
513 | "metadata": {
514 | "slideshow": {
515 | "slide_type": "fragment"
516 | }
517 | },
518 | "outputs": [],
519 | "source": [
520 | "distance = nx.shortest_path_length(G, origin_node, destination_node, weight='length')\n",
521 | "distance\n"
522 | ]
523 | },
524 | {
525 | "cell_type": "code",
526 | "execution_count": null,
527 | "metadata": {
528 | "slideshow": {
529 | "slide_type": "slide"
530 | }
531 | },
532 | "outputs": [],
533 | "source": [
534 | "# Encontrar el camino más corto entre los puntos de origen y destino\n",
535 | "route = nx.shortest_path(G, origin_node, destination_node, weight='length')\n",
536 | "str(route)"
537 | ]
538 | },
539 | {
540 | "cell_type": "code",
541 | "execution_count": null,
542 | "metadata": {
543 | "slideshow": {
544 | "slide_type": "slide"
545 | }
546 | },
547 | "outputs": [],
548 | "source": [
549 | "# plot the route showing origin/destination lat-long points in blue\n",
550 | "fig, ax = ox.plot_graph_route(G, route, origin_point=origin_point, destination_point=destination_point)"
551 | ]
552 | },
553 | {
554 | "cell_type": "markdown",
555 | "metadata": {
556 | "slideshow": {
557 | "slide_type": "slide"
558 | }
559 | },
560 | "source": [
561 | "# Ejercicios\n",
562 | "\n",
563 | "1. Calcular la distancia más corta entre tu casa y la universidad.\n",
564 | "2. ¿Qué otros usos se le pueden dar a estos datos?"
565 | ]
566 | },
567 | {
568 | "cell_type": "code",
569 | "execution_count": null,
570 | "metadata": {
571 | "slideshow": {
572 | "slide_type": "slide"
573 | }
574 | },
575 | "outputs": [],
576 | "source": [
577 | "#Si se descargar el mapa de toda la región metropolitana\n",
578 | "#G = ox.graph_from_place('Provincia de Santiago, Chile', network_type='drive')\n"
579 | ]
580 | },
581 | {
582 | "cell_type": "markdown",
583 | "metadata": {
584 | "slideshow": {
585 | "slide_type": "slide"
586 | }
587 | },
588 | "source": [
589 | " Más sobre OSMNX "
590 | ]
591 | },
592 | {
593 | "cell_type": "code",
594 | "execution_count": null,
595 | "metadata": {
596 | "slideshow": {
597 | "slide_type": "slide"
598 | }
599 | },
600 | "outputs": [],
601 | "source": [
602 | "import osmnx as ox\n",
603 | "import networkx as nx\n",
604 | "import matplotlib.cm as cm\n",
605 | "import matplotlib.colors as colors\n",
606 | "import pandas as pd\n",
607 | "%matplotlib inline\n",
608 | "ox.config(log_console=True, use_cache=True)"
609 | ]
610 | },
611 | {
612 | "cell_type": "markdown",
613 | "metadata": {},
614 | "source": [
615 | "# Descargar Mapa"
616 | ]
617 | },
618 | {
619 | "cell_type": "code",
620 | "execution_count": null,
621 | "metadata": {
622 | "slideshow": {
623 | "slide_type": "slide"
624 | }
625 | },
626 | "outputs": [],
627 | "source": [
628 | "# Veamos una ciudad de estados unidos\n",
629 | "#M = ox.graph_from_place('Piedmont, California', network_type='drive') #walk para ver senderos\n",
630 | "#M = ox.project_graph(M)\n",
631 | "#ox.save_graphml(M, filename='./USA-piedmont.graphml')\n",
632 | "\n"
633 | ]
634 | },
635 | {
636 | "cell_type": "markdown",
637 | "metadata": {
638 | "slideshow": {
639 | "slide_type": "slide"
640 | }
641 | },
642 | "source": [
643 | "# Cargar mapa y mostrarlo"
644 | ]
645 | },
646 | {
647 | "cell_type": "code",
648 | "execution_count": null,
649 | "metadata": {
650 | "slideshow": {
651 | "slide_type": "fragment"
652 | }
653 | },
654 | "outputs": [],
655 | "source": [
656 | "M = ox.load_graphml('./USA-piedmont.graphml')\n",
657 | "fig, ax = ox.plot_graph(M, bgcolor='k', node_size=30, node_color='#999999', node_edgecolor='none', node_zorder=2,\n",
658 | " edge_color='#555555', edge_linewidth=1.5, edge_alpha=1)"
659 | ]
660 | },
661 | {
662 | "cell_type": "markdown",
663 | "metadata": {
664 | "slideshow": {
665 | "slide_type": "slide"
666 | }
667 | },
668 | "source": [
669 | "# Calcular y visualizar nodos centrales"
670 | ]
671 | },
672 | {
673 | "cell_type": "code",
674 | "execution_count": null,
675 | "metadata": {
676 | "slideshow": {
677 | "slide_type": "fragment"
678 | }
679 | },
680 | "outputs": [],
681 | "source": [
682 | "node_centrality = nx.closeness_centrality(M)\n"
683 | ]
684 | },
685 | {
686 | "cell_type": "code",
687 | "execution_count": null,
688 | "metadata": {
689 | "slideshow": {
690 | "slide_type": "fragment"
691 | }
692 | },
693 | "outputs": [],
694 | "source": [
695 | "# Mostremoslo\n",
696 | "df = pd.DataFrame(data=pd.Series(node_centrality).sort_values(), columns=['cc'])\n",
697 | "df['colors'] = ox.get_colors(n=len(df), cmap='inferno', start=0.2)\n",
698 | "df = df.reindex(M.nodes())\n",
699 | "nc = df['colors'].tolist()\n",
700 | "fig, ax = ox.plot_graph(M, bgcolor='k', node_size=30, node_color=nc, node_edgecolor='none', node_zorder=2,\n",
701 | " edge_color='#555555', edge_linewidth=1.5, edge_alpha=1)"
702 | ]
703 | },
704 | {
705 | "cell_type": "markdown",
706 | "metadata": {
707 | "slideshow": {
708 | "slide_type": "slide"
709 | }
710 | },
711 | "source": [
712 | " Revisando el arco del triunfo "
713 | ]
714 | },
715 | {
716 | "cell_type": "code",
717 | "execution_count": null,
718 | "metadata": {
719 | "slideshow": {
720 | "slide_type": "slide"
721 | }
722 | },
723 | "outputs": [],
724 | "source": [
725 | "import osmnx as ox\n",
726 | "from IPython.display import Image\n",
727 | "\n",
728 | "# configurar \n",
729 | "img_folder = 'images'\n",
730 | "extension = 'png'\n",
731 | "size = 240"
732 | ]
733 | },
734 | {
735 | "cell_type": "code",
736 | "execution_count": null,
737 | "metadata": {
738 | "slideshow": {
739 | "slide_type": "slide"
740 | }
741 | },
742 | "outputs": [],
743 | "source": [
744 | "point = (48.873446, 2.294255)\n",
745 | "dist = 612\n",
746 | "gdf = ox.buildings_from_point(point=point, distance=dist)\n",
747 | "gdf_proj = ox.project_gdf(gdf)\n",
748 | "bbox = ox.bbox_from_point(point=point, distance=dist, project_utm=True)\n",
749 | "fig, ax = ox.plot_buildings(gdf_proj, bgcolor='#333333', color='w', figsize=(4,4), bbox=bbox,\n",
750 | " save=True, show=False, close=True, filename='paris_bldgs', dpi=90)\n",
751 | "Image('{}/{}.{}'.format(img_folder, 'paris_bldgs', extension), height=size, width=size)"
752 | ]
753 | },
754 | {
755 | "cell_type": "markdown",
756 | "metadata": {
757 | "slideshow": {
758 | "slide_type": "fragment"
759 | }
760 | },
761 | "source": [
762 | "# ¡Que engorroso :( !"
763 | ]
764 | },
765 | {
766 | "cell_type": "markdown",
767 | "metadata": {
768 | "slideshow": {
769 | "slide_type": "slide"
770 | }
771 | },
772 | "source": [
773 | "# Ahora con funciones"
774 | ]
775 | },
776 | {
777 | "cell_type": "code",
778 | "execution_count": null,
779 | "metadata": {
780 | "slideshow": {
781 | "slide_type": "fragment"
782 | }
783 | },
784 | "outputs": [],
785 | "source": [
786 | "# helper funcion to get one-square-mile street networks, building footprints, and plot them\n",
787 | "def make_plot(place, point, network_type='drive', bldg_color='orange', dpi=40,\n",
788 | " dist=805, default_width=4, street_widths=None):\n",
789 | " gdf = ox.buildings_from_point(point=point, distance=dist)\n",
790 | " gdf_proj = ox.project_gdf(gdf)\n",
791 | " fig, ax = ox.plot_figure_ground(point=point, dist=dist, network_type=network_type, default_width=default_width,\n",
792 | " street_widths=street_widths, save=False, show=False, close=True)\n",
793 | " fig, ax = ox.plot_buildings(gdf_proj, fig=fig, ax=ax, color=bldg_color, set_bounds=False,\n",
794 | " save=True, show=False, close=True, filename=place, dpi=dpi)"
795 | ]
796 | },
797 | {
798 | "cell_type": "code",
799 | "execution_count": null,
800 | "metadata": {
801 | "slideshow": {
802 | "slide_type": "fragment"
803 | }
804 | },
805 | "outputs": [],
806 | "source": [
807 | "point = (48.873446, 2.294255)\n",
808 | "place = 'paris_bldgs'\n",
809 | "\n",
810 | "make_plot(place, point)\n",
811 | "Image('{}/{}.{}'.format(img_folder, place, extension), height=size, width=size)\n"
812 | ]
813 | },
814 | {
815 | "cell_type": "markdown",
816 | "metadata": {
817 | "slideshow": {
818 | "slide_type": "slide"
819 | }
820 | },
821 | "source": [
822 | "# Obtener principales estadísticas\n",
823 | "\n",
824 | "### Documentación: https://osmnx.readthedocs.io/en/stable/osmnx.html#module-osmnx.stats"
825 | ]
826 | },
827 | {
828 | "cell_type": "code",
829 | "execution_count": null,
830 | "metadata": {
831 | "slideshow": {
832 | "slide_type": "fragment"
833 | }
834 | },
835 | "outputs": [],
836 | "source": [
837 | "basic_stats = ox.basic_stats(M)\n",
838 | "for key in basic_stats:\n",
839 | " print key, basic_stats[key]"
840 | ]
841 | },
842 | {
843 | "cell_type": "markdown",
844 | "metadata": {
845 | "slideshow": {
846 | "slide_type": "slide"
847 | }
848 | },
849 | "source": [
850 | "# Obtener mayor información\n",
851 | "### turn on/ turn off análisis topológicos\n"
852 | ]
853 | },
854 | {
855 | "cell_type": "code",
856 | "execution_count": null,
857 | "metadata": {
858 | "slideshow": {
859 | "slide_type": "fragment"
860 | }
861 | },
862 | "outputs": [],
863 | "source": [
864 | "more_stats = ox.extended_stats(M, ecc=True, bc=True, cc=True) \n",
865 | "for key in sorted(more_stats.keys()):\n",
866 | " print(key)"
867 | ]
868 | },
869 | {
870 | "cell_type": "markdown",
871 | "metadata": {
872 | "slideshow": {
873 | "slide_type": "slide"
874 | }
875 | },
876 | "source": [
877 | " ¿Preguntas? "
878 | ]
879 | }
880 | ],
881 | "metadata": {
882 | "anaconda-cloud": {},
883 | "celltoolbar": "Slideshow",
884 | "kernelspec": {
885 | "display_name": "Python 2",
886 | "language": "python",
887 | "name": "python2"
888 | },
889 | "language_info": {
890 | "codemirror_mode": {
891 | "name": "ipython",
892 | "version": 2
893 | },
894 | "file_extension": ".py",
895 | "mimetype": "text/x-python",
896 | "name": "python",
897 | "nbconvert_exporter": "python",
898 | "pygments_lexer": "ipython2",
899 | "version": "2.7.14"
900 | }
901 | },
902 | "nbformat": 4,
903 | "nbformat_minor": 1
904 | }
905 |
--------------------------------------------------------------------------------
/Clase 1/boeing-osmnx-street-networks.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 1/boeing-osmnx-street-networks.pdf
--------------------------------------------------------------------------------
/Clase 1/images/paris_bldgs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 1/images/paris_bldgs.png
--------------------------------------------------------------------------------
/Clase 1/images/piedmont_bldgs.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 1/images/piedmont_bldgs.png
--------------------------------------------------------------------------------
/Clase 1/img/datagramas.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 1/img/datagramas.png
--------------------------------------------------------------------------------
/Clase 1/img/libro.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 1/img/libro.png
--------------------------------------------------------------------------------
/Clase 1/img/wikipedia_song.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 1/img/wikipedia_song.png
--------------------------------------------------------------------------------
/Clase 2/02_introducción_a_pandas-Formato-Estudiantes.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "slideshow": {
7 | "slide_type": "slide"
8 | }
9 | },
10 | "source": [
11 | "\n",
12 | " \n",
13 | "\n",
14 | " \n",
15 | "\n",
16 | "# Taller de Manejo y Visualización de Datos con Python\n",
17 | "### Introducción a Pandas \n",
18 | "\n",
19 | "Felipe González P. \n",
20 | "felipe.gonzalezp.12@sansano.usm.cl \n",
21 | "\n",
22 | "\n",
23 | "\n",
24 | "\n"
25 | ]
26 | },
27 | {
28 | "cell_type": "markdown",
29 | "metadata": {
30 | "slideshow": {
31 | "slide_type": "slide"
32 | }
33 | },
34 | "source": [
35 | "## ¿Qué es Numpy?"
36 | ]
37 | },
38 | {
39 | "cell_type": "markdown",
40 | "metadata": {
41 | "slideshow": {
42 | "slide_type": "fragment"
43 | }
44 | },
45 | "source": [
46 | "Numpy es extensión de Python que le agrega mayor soporte para vectores y matrices, constituyendo una biblioteca de funciones matemáticas de alto nivel para operar con estos elementos. "
47 | ]
48 | },
49 | {
50 | "cell_type": "markdown",
51 | "metadata": {
52 | "slideshow": {
53 | "slide_type": "slide"
54 | }
55 | },
56 | "source": [
57 | "## Ejemplo"
58 | ]
59 | },
60 | {
61 | "cell_type": "code",
62 | "execution_count": null,
63 | "metadata": {
64 | "slideshow": {
65 | "slide_type": "fragment"
66 | }
67 | },
68 | "outputs": [],
69 | "source": [
70 | "import numpy\n",
71 | "from matplotlib import pyplot\n",
72 | "%matplotlib inline\n",
73 | "x = numpy.linspace(0, 2 * numpy.pi,10) #variemos el último valor. 50 es el valor por defecto\n",
74 | "y = numpy.sin(x)\n",
75 | "pyplot.plot(x, y)\n",
76 | "pyplot.show()\n",
77 | "\n"
78 | ]
79 | },
80 | {
81 | "cell_type": "markdown",
82 | "metadata": {
83 | "slideshow": {
84 | "slide_type": "slide"
85 | }
86 | },
87 | "source": [
88 | "## ¿Qué es Pandas?"
89 | ]
90 | },
91 | {
92 | "cell_type": "markdown",
93 | "metadata": {
94 | "slideshow": {
95 | "slide_type": "fragment"
96 | }
97 | },
98 | "source": [
99 | "* Es una librería escrita como extensión de Numpy para la manipulación y análisis de datos en Python. \n",
100 | "* Resuelve las limitaciones que tiene Numpy\n",
101 | "* Muy útil para trabajar con data que no está muy bien organizada. "
102 | ]
103 | },
104 | {
105 | "cell_type": "markdown",
106 | "metadata": {
107 | "slideshow": {
108 | "slide_type": "slide"
109 | }
110 | },
111 | "source": [
112 | " "
113 | ]
114 | },
115 | {
116 | "cell_type": "markdown",
117 | "metadata": {
118 | "slideshow": {
119 | "slide_type": "slide"
120 | }
121 | },
122 | "source": [
123 | "\n",
124 | "## Importar Pandas\n"
125 | ]
126 | },
127 | {
128 | "cell_type": "code",
129 | "execution_count": null,
130 | "metadata": {
131 | "slideshow": {
132 | "slide_type": "fragment"
133 | }
134 | },
135 | "outputs": [],
136 | "source": [
137 | "import pandas as pd\n",
138 | "pd.__version__\n"
139 | ]
140 | },
141 | {
142 | "cell_type": "markdown",
143 | "metadata": {
144 | "slideshow": {
145 | "slide_type": "slide"
146 | }
147 | },
148 | "source": [
149 | "# Recordemos"
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": null,
155 | "metadata": {
156 | "slideshow": {
157 | "slide_type": "fragment"
158 | }
159 | },
160 | "outputs": [],
161 | "source": [
162 | "#pd.\n",
163 | "pd?"
164 | ]
165 | },
166 | {
167 | "cell_type": "markdown",
168 | "metadata": {
169 | "slideshow": {
170 | "slide_type": "slide"
171 | }
172 | },
173 | "source": [
174 | " ¿Qué haremos con Pandas? "
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {
180 | "slideshow": {
181 | "slide_type": "slide"
182 | }
183 | },
184 | "source": [
185 | "# Data Munging\n",
186 | "\n",
187 | "Es el proceso de transformar datos \"puros\" en otro formato con el objetivo de hacerlos más apropiados y valioso para propósitos de análisis. \n"
188 | ]
189 | },
190 | {
191 | "cell_type": "markdown",
192 | "metadata": {
193 | "slideshow": {
194 | "slide_type": "slide"
195 | }
196 | },
197 | "source": [
198 | "# Usar Pandas para Análisis de datos \n",
199 | "## Data Munging\n",
200 | "\n",
201 | "Basado en: WaveDataLab "
202 | ]
203 | },
204 | {
205 | "cell_type": "markdown",
206 | "metadata": {
207 | "slideshow": {
208 | "slide_type": "slide"
209 | }
210 | },
211 | "source": [
212 | "Importar librerías"
213 | ]
214 | },
215 | {
216 | "cell_type": "code",
217 | "execution_count": null,
218 | "metadata": {
219 | "slideshow": {
220 | "slide_type": "fragment"
221 | }
222 | },
223 | "outputs": [],
224 | "source": [
225 | "%matplotlib\n",
226 | "import numpy as np\n",
227 | "import pandas as pd"
228 | ]
229 | },
230 | {
231 | "cell_type": "markdown",
232 | "metadata": {
233 | "slideshow": {
234 | "slide_type": "slide"
235 | }
236 | },
237 | "source": [
238 | "Leer archivo CSV"
239 | ]
240 | },
241 | {
242 | "cell_type": "code",
243 | "execution_count": null,
244 | "metadata": {
245 | "slideshow": {
246 | "slide_type": "fragment"
247 | }
248 | },
249 | "outputs": [],
250 | "source": [
251 | "ver=pd.read_csv(\"SalesJan2009.csv\",\";\")\n"
252 | ]
253 | },
254 | {
255 | "cell_type": "markdown",
256 | "metadata": {
257 | "slideshow": {
258 | "slide_type": "slide"
259 | }
260 | },
261 | "source": [
262 | "Ver las primeras filas de un archivo"
263 | ]
264 | },
265 | {
266 | "cell_type": "code",
267 | "execution_count": null,
268 | "metadata": {
269 | "slideshow": {
270 | "slide_type": "fragment"
271 | }
272 | },
273 | "outputs": [],
274 | "source": [
275 | "ver.head(100)"
276 | ]
277 | },
278 | {
279 | "cell_type": "markdown",
280 | "metadata": {
281 | "slideshow": {
282 | "slide_type": "slide"
283 | }
284 | },
285 | "source": [
286 | "Encontrar el número de filas y columnas de un archivo"
287 | ]
288 | },
289 | {
290 | "cell_type": "code",
291 | "execution_count": null,
292 | "metadata": {
293 | "slideshow": {
294 | "slide_type": "fragment"
295 | }
296 | },
297 | "outputs": [],
298 | "source": [
299 | "ver.shape\n"
300 | ]
301 | },
302 | {
303 | "cell_type": "markdown",
304 | "metadata": {
305 | "slideshow": {
306 | "slide_type": "fragment"
307 | }
308 | },
309 | "source": [
310 | "Encontrar el número de filas"
311 | ]
312 | },
313 | {
314 | "cell_type": "code",
315 | "execution_count": null,
316 | "metadata": {
317 | "slideshow": {
318 | "slide_type": "fragment"
319 | }
320 | },
321 | "outputs": [],
322 | "source": [
323 | "len(ver)"
324 | ]
325 | },
326 | {
327 | "cell_type": "markdown",
328 | "metadata": {
329 | "slideshow": {
330 | "slide_type": "fragment"
331 | }
332 | },
333 | "source": [
334 | "Encontrar los nombres de las columnas"
335 | ]
336 | },
337 | {
338 | "cell_type": "code",
339 | "execution_count": null,
340 | "metadata": {
341 | "slideshow": {
342 | "slide_type": "fragment"
343 | }
344 | },
345 | "outputs": [],
346 | "source": [
347 | "ver.columns"
348 | ]
349 | },
350 | {
351 | "cell_type": "markdown",
352 | "metadata": {
353 | "slideshow": {
354 | "slide_type": "slide"
355 | }
356 | },
357 | "source": [
358 | "Mostrar las primeras 5 filas de una determinada columna"
359 | ]
360 | },
361 | {
362 | "cell_type": "code",
363 | "execution_count": null,
364 | "metadata": {
365 | "slideshow": {
366 | "slide_type": "fragment"
367 | }
368 | },
369 | "outputs": [],
370 | "source": [
371 | "ver['Name'][:5]"
372 | ]
373 | },
374 | {
375 | "cell_type": "markdown",
376 | "metadata": {
377 | "slideshow": {
378 | "slide_type": "slide"
379 | }
380 | },
381 | "source": [
382 | "### Crear rangos categóricos para datos numéricos. \n",
383 | "\n",
384 | "\n",
385 | "*Se puede especificar la cantidad de rangos que se desea* \n",
386 | "\n",
387 | "¿Cuando es útil? Cuando se desea convertir edades en rangos etarios"
388 | ]
389 | },
390 | {
391 | "cell_type": "code",
392 | "execution_count": null,
393 | "metadata": {
394 | "slideshow": {
395 | "slide_type": "slide"
396 | }
397 | },
398 | "outputs": [],
399 | "source": [
400 | "latitudes = pd.cut(ver['Latitude'], 5)\n",
401 | "latitudes[:5]\n",
402 | "#Notar que son equispaciados"
403 | ]
404 | },
405 | {
406 | "cell_type": "markdown",
407 | "metadata": {
408 | "slideshow": {
409 | "slide_type": "slide"
410 | }
411 | },
412 | "source": [
413 | "¿Cuántos filas hay por cada rango?"
414 | ]
415 | },
416 | {
417 | "cell_type": "code",
418 | "execution_count": null,
419 | "metadata": {
420 | "slideshow": {
421 | "slide_type": "fragment"
422 | }
423 | },
424 | "outputs": [],
425 | "source": [
426 | "pd.value_counts(latitudes)\n"
427 | ]
428 | },
429 | {
430 | "cell_type": "markdown",
431 | "metadata": {
432 | "slideshow": {
433 | "slide_type": "slide"
434 | }
435 | },
436 | "source": [
437 | "Ordenar los datos dada una determinada columna"
438 | ]
439 | },
440 | {
441 | "cell_type": "code",
442 | "execution_count": null,
443 | "metadata": {
444 | "slideshow": {
445 | "slide_type": "fragment"
446 | }
447 | },
448 | "outputs": [],
449 | "source": [
450 | "ver.sort_values(by=['Price'])"
451 | ]
452 | },
453 | {
454 | "cell_type": "markdown",
455 | "metadata": {
456 | "slideshow": {
457 | "slide_type": "slide"
458 | }
459 | },
460 | "source": [
461 | "Ordenar por múltiples columnas"
462 | ]
463 | },
464 | {
465 | "cell_type": "code",
466 | "execution_count": null,
467 | "metadata": {
468 | "slideshow": {
469 | "slide_type": "fragment"
470 | }
471 | },
472 | "outputs": [],
473 | "source": [
474 | "ver.sort_values(by=['Transaction_date','Last_Login'])[:5]\n"
475 | ]
476 | },
477 | {
478 | "cell_type": "markdown",
479 | "metadata": {
480 | "slideshow": {
481 | "slide_type": "slide"
482 | }
483 | },
484 | "source": [
485 | "Poner NaN primero"
486 | ]
487 | },
488 | {
489 | "cell_type": "code",
490 | "execution_count": null,
491 | "metadata": {
492 | "slideshow": {
493 | "slide_type": "fragment"
494 | }
495 | },
496 | "outputs": [],
497 | "source": [
498 | "ver.sort_values(by='Payment_Type', ascending=False, na_position='first')\n"
499 | ]
500 | },
501 | {
502 | "cell_type": "markdown",
503 | "metadata": {
504 | "slideshow": {
505 | "slide_type": "slide"
506 | }
507 | },
508 | "source": [
509 | "Contar valores de una determinada columna"
510 | ]
511 | },
512 | {
513 | "cell_type": "code",
514 | "execution_count": null,
515 | "metadata": {
516 | "slideshow": {
517 | "slide_type": "fragment"
518 | }
519 | },
520 | "outputs": [],
521 | "source": [
522 | "ver['Payment_Type'].value_counts()\n",
523 | "#NaN no aparece"
524 | ]
525 | },
526 | {
527 | "cell_type": "markdown",
528 | "metadata": {
529 | "slideshow": {
530 | "slide_type": "slide"
531 | }
532 | },
533 | "source": [
534 | "Encontrar los tipos de cada columna"
535 | ]
536 | },
537 | {
538 | "cell_type": "code",
539 | "execution_count": null,
540 | "metadata": {
541 | "slideshow": {
542 | "slide_type": "fragment"
543 | }
544 | },
545 | "outputs": [],
546 | "source": [
547 | "ver.dtypes\n"
548 | ]
549 | },
550 | {
551 | "cell_type": "markdown",
552 | "metadata": {
553 | "slideshow": {
554 | "slide_type": "slide"
555 | }
556 | },
557 | "source": [
558 | "Obtener los valores únicos de una columna"
559 | ]
560 | },
561 | {
562 | "cell_type": "code",
563 | "execution_count": null,
564 | "metadata": {
565 | "slideshow": {
566 | "slide_type": "fragment"
567 | }
568 | },
569 | "outputs": [],
570 | "source": [
571 | "ver['Country'].unique()\n"
572 | ]
573 | },
574 | {
575 | "cell_type": "markdown",
576 | "metadata": {
577 | "slideshow": {
578 | "slide_type": "slide"
579 | }
580 | },
581 | "source": [
582 | "# Mini Ejercicio\n",
583 | "## ¿A cuantos países se envía mercadería?"
584 | ]
585 | },
586 | {
587 | "cell_type": "code",
588 | "execution_count": null,
589 | "metadata": {
590 | "slideshow": {
591 | "slide_type": "fragment"
592 | }
593 | },
594 | "outputs": [],
595 | "source": []
596 | },
597 | {
598 | "cell_type": "markdown",
599 | "metadata": {
600 | "slideshow": {
601 | "slide_type": "slide"
602 | }
603 | },
604 | "source": [
605 | "Hacer comparaciones"
606 | ]
607 | },
608 | {
609 | "cell_type": "code",
610 | "execution_count": null,
611 | "metadata": {
612 | "slideshow": {
613 | "slide_type": "fragment"
614 | }
615 | },
616 | "outputs": [],
617 | "source": [
618 | "ver.loc[0:3,'Payment_Type'] == \"Visa\"\n"
619 | ]
620 | },
621 | {
622 | "cell_type": "markdown",
623 | "metadata": {
624 | "slideshow": {
625 | "slide_type": "slide"
626 | }
627 | },
628 | "source": [
629 | " Ejercicios "
630 | ]
631 | },
632 | {
633 | "cell_type": "markdown",
634 | "metadata": {
635 | "slideshow": {
636 | "slide_type": "slide"
637 | }
638 | },
639 | "source": [
640 | "# Parte 1: Obtener y explorar los datos\n",
641 | "Agradecimientos a : Guilherme Samora y Kevin Markham \n",
642 | "\n",
643 | "### Importar pandas y numpy"
644 | ]
645 | },
646 | {
647 | "cell_type": "code",
648 | "execution_count": null,
649 | "metadata": {
650 | "slideshow": {
651 | "slide_type": "fragment"
652 | }
653 | },
654 | "outputs": [],
655 | "source": []
656 | },
657 | {
658 | "cell_type": "markdown",
659 | "metadata": {
660 | "slideshow": {
661 | "slide_type": "slide"
662 | }
663 | },
664 | "source": [
665 | "### Observar/Descargar los documentos desde [esta dirección](https://raw.githubusercontent.com/justmarkham/DAT8/master/data/chipotle.tsv). \n",
666 | "\n",
667 | "### Los datos deben quedar almacenados en una variable"
668 | ]
669 | },
670 | {
671 | "cell_type": "code",
672 | "execution_count": null,
673 | "metadata": {
674 | "slideshow": {
675 | "slide_type": "fragment"
676 | }
677 | },
678 | "outputs": [],
679 | "source": []
680 | },
681 | {
682 | "cell_type": "markdown",
683 | "metadata": {
684 | "slideshow": {
685 | "slide_type": "slide"
686 | }
687 | },
688 | "source": [
689 | "### Mostrar las primeras 10 filas"
690 | ]
691 | },
692 | {
693 | "cell_type": "code",
694 | "execution_count": null,
695 | "metadata": {
696 | "slideshow": {
697 | "slide_type": "fragment"
698 | }
699 | },
700 | "outputs": [],
701 | "source": []
702 | },
703 | {
704 | "cell_type": "markdown",
705 | "metadata": {
706 | "slideshow": {
707 | "slide_type": "slide"
708 | }
709 | },
710 | "source": [
711 | "## Mostrar 'choice_description' del quinto elemento del dataset"
712 | ]
713 | },
714 | {
715 | "cell_type": "code",
716 | "execution_count": null,
717 | "metadata": {
718 | "slideshow": {
719 | "slide_type": "fragment"
720 | }
721 | },
722 | "outputs": [],
723 | "source": []
724 | },
725 | {
726 | "cell_type": "markdown",
727 | "metadata": {
728 | "slideshow": {
729 | "slide_type": "slide"
730 | }
731 | },
732 | "source": [
733 | "### ¿Cuál es el número de filas en el dataset?"
734 | ]
735 | },
736 | {
737 | "cell_type": "code",
738 | "execution_count": null,
739 | "metadata": {
740 | "slideshow": {
741 | "slide_type": "fragment"
742 | }
743 | },
744 | "outputs": [],
745 | "source": []
746 | },
747 | {
748 | "cell_type": "markdown",
749 | "metadata": {
750 | "slideshow": {
751 | "slide_type": "slide"
752 | }
753 | },
754 | "source": [
755 | "### ¿Cuál es el número de columnas?"
756 | ]
757 | },
758 | {
759 | "cell_type": "code",
760 | "execution_count": null,
761 | "metadata": {
762 | "slideshow": {
763 | "slide_type": "fragment"
764 | }
765 | },
766 | "outputs": [],
767 | "source": []
768 | },
769 | {
770 | "cell_type": "markdown",
771 | "metadata": {
772 | "slideshow": {
773 | "slide_type": "slide"
774 | }
775 | },
776 | "source": [
777 | "### ¿Cuántos productos se vendieron en total?"
778 | ]
779 | },
780 | {
781 | "cell_type": "code",
782 | "execution_count": null,
783 | "metadata": {
784 | "slideshow": {
785 | "slide_type": "fragment"
786 | }
787 | },
788 | "outputs": [],
789 | "source": []
790 | },
791 | {
792 | "cell_type": "markdown",
793 | "metadata": {
794 | "slideshow": {
795 | "slide_type": "slide"
796 | }
797 | },
798 | "source": [
799 | "### ¿Cuál fue la ganancia total?\n"
800 | ]
801 | },
802 | {
803 | "cell_type": "code",
804 | "execution_count": null,
805 | "metadata": {
806 | "slideshow": {
807 | "slide_type": "fragment"
808 | }
809 | },
810 | "outputs": [],
811 | "source": []
812 | },
813 | {
814 | "cell_type": "markdown",
815 | "metadata": {
816 | "slideshow": {
817 | "slide_type": "slide"
818 | }
819 | },
820 | "source": [
821 | "### ¿Cuántas ordenes se generaron?"
822 | ]
823 | },
824 | {
825 | "cell_type": "code",
826 | "execution_count": null,
827 | "metadata": {
828 | "slideshow": {
829 | "slide_type": "fragment"
830 | }
831 | },
832 | "outputs": [],
833 | "source": []
834 | },
835 | {
836 | "cell_type": "markdown",
837 | "metadata": {
838 | "slideshow": {
839 | "slide_type": "slide"
840 | }
841 | },
842 | "source": [
843 | "### ¿Cuántos diferentes productos se vendieron?"
844 | ]
845 | },
846 | {
847 | "cell_type": "code",
848 | "execution_count": null,
849 | "metadata": {
850 | "slideshow": {
851 | "slide_type": "fragment"
852 | }
853 | },
854 | "outputs": [],
855 | "source": []
856 | },
857 | {
858 | "cell_type": "markdown",
859 | "metadata": {
860 | "slideshow": {
861 | "slide_type": "slide"
862 | }
863 | },
864 | "source": [
865 | "### ¿Cuántos productos cuentan más de $10.00?"
866 | ]
867 | },
868 | {
869 | "cell_type": "code",
870 | "execution_count": null,
871 | "metadata": {
872 | "slideshow": {
873 | "slide_type": "fragment"
874 | }
875 | },
876 | "outputs": [],
877 | "source": []
878 | },
879 | {
880 | "cell_type": "markdown",
881 | "metadata": {
882 | "slideshow": {
883 | "slide_type": "slide"
884 | }
885 | },
886 | "source": [
887 | "### De los productos que se vendieron solo una vez ¿Cuál es el precio para cada item?"
888 | ]
889 | },
890 | {
891 | "cell_type": "code",
892 | "execution_count": null,
893 | "metadata": {
894 | "slideshow": {
895 | "slide_type": "fragment"
896 | }
897 | },
898 | "outputs": [],
899 | "source": []
900 | },
901 | {
902 | "cell_type": "markdown",
903 | "metadata": {
904 | "slideshow": {
905 | "slide_type": "slide"
906 | }
907 | },
908 | "source": [
909 | "### Ordenar productos por nombre"
910 | ]
911 | },
912 | {
913 | "cell_type": "code",
914 | "execution_count": null,
915 | "metadata": {
916 | "slideshow": {
917 | "slide_type": "fragment"
918 | }
919 | },
920 | "outputs": [],
921 | "source": []
922 | },
923 | {
924 | "cell_type": "markdown",
925 | "metadata": {
926 | "slideshow": {
927 | "slide_type": "slide"
928 | }
929 | },
930 | "source": [
931 | "### ¿Cuál es el producto más caro? ¿A qué precio se vende?"
932 | ]
933 | },
934 | {
935 | "cell_type": "code",
936 | "execution_count": null,
937 | "metadata": {
938 | "slideshow": {
939 | "slide_type": "fragment"
940 | }
941 | },
942 | "outputs": [],
943 | "source": []
944 | },
945 | {
946 | "cell_type": "markdown",
947 | "metadata": {
948 | "slideshow": {
949 | "slide_type": "slide"
950 | }
951 | },
952 | "source": [
953 | "### ¿Cuánta gente ordenó \"Veggie Salad Bowl\"?"
954 | ]
955 | },
956 | {
957 | "cell_type": "code",
958 | "execution_count": null,
959 | "metadata": {
960 | "slideshow": {
961 | "slide_type": "fragment"
962 | }
963 | },
964 | "outputs": [],
965 | "source": []
966 | },
967 | {
968 | "cell_type": "markdown",
969 | "metadata": {
970 | "slideshow": {
971 | "slide_type": "slide"
972 | }
973 | },
974 | "source": [
975 | "### ¿Cuántas veces las personas ordenaron más de una \"Canned Soda\"?"
976 | ]
977 | },
978 | {
979 | "cell_type": "code",
980 | "execution_count": null,
981 | "metadata": {
982 | "slideshow": {
983 | "slide_type": "fragment"
984 | }
985 | },
986 | "outputs": [],
987 | "source": []
988 | },
989 | {
990 | "cell_type": "markdown",
991 | "metadata": {
992 | "slideshow": {
993 | "slide_type": "slide"
994 | }
995 | },
996 | "source": [
997 | " Agrupar datos por columnas con .groupby()\n",
998 | " "
999 | ]
1000 | },
1001 | {
1002 | "cell_type": "markdown",
1003 | "metadata": {
1004 | "slideshow": {
1005 | "slide_type": "slide"
1006 | }
1007 | },
1008 | "source": [
1009 | "### ¿Cuál es el producto más solicitado?"
1010 | ]
1011 | },
1012 | {
1013 | "cell_type": "code",
1014 | "execution_count": null,
1015 | "metadata": {
1016 | "slideshow": {
1017 | "slide_type": "fragment"
1018 | }
1019 | },
1020 | "outputs": [],
1021 | "source": [
1022 | "c = chipo.groupby('item_name')\n",
1023 | "c = c.sum()\n",
1024 | "c = c.sort_values(['quantity'], ascending=False)\n",
1025 | "c.head(1)"
1026 | ]
1027 | },
1028 | {
1029 | "cell_type": "markdown",
1030 | "metadata": {
1031 | "slideshow": {
1032 | "slide_type": "slide"
1033 | }
1034 | },
1035 | "source": [
1036 | "### ¿Cuántos items de este producto fueron pedidos?"
1037 | ]
1038 | },
1039 | {
1040 | "cell_type": "code",
1041 | "execution_count": null,
1042 | "metadata": {
1043 | "slideshow": {
1044 | "slide_type": "fragment"
1045 | }
1046 | },
1047 | "outputs": [],
1048 | "source": [
1049 | "c = chipo.groupby('item_name')\n",
1050 | "c = c.sum()\n",
1051 | "c = c.sort_values(['quantity'], ascending=False)\n",
1052 | "c.head(1)"
1053 | ]
1054 | },
1055 | {
1056 | "cell_type": "markdown",
1057 | "metadata": {
1058 | "slideshow": {
1059 | "slide_type": "slide"
1060 | }
1061 | },
1062 | "source": [
1063 | "### ¿Cuánto vale en promedio los productos del local?"
1064 | ]
1065 | },
1066 | {
1067 | "cell_type": "code",
1068 | "execution_count": null,
1069 | "metadata": {
1070 | "slideshow": {
1071 | "slide_type": "fragment"
1072 | }
1073 | },
1074 | "outputs": [],
1075 | "source": [
1076 | "chipo.groupby(by=['order_id']).sum().mean()['item_price']\n"
1077 | ]
1078 | },
1079 | {
1080 | "cell_type": "markdown",
1081 | "metadata": {
1082 | "slideshow": {
1083 | "slide_type": "slide"
1084 | }
1085 | },
1086 | "source": [
1087 | "### ¿Cuándo fue el elemento más pedido según 'choice_description' ?"
1088 | ]
1089 | },
1090 | {
1091 | "cell_type": "code",
1092 | "execution_count": null,
1093 | "metadata": {
1094 | "slideshow": {
1095 | "slide_type": "fragment"
1096 | }
1097 | },
1098 | "outputs": [],
1099 | "source": [
1100 | "c = chipo.groupby('choice_description').sum()\n",
1101 | "c = c.sort_values(['quantity'], ascending=False)\n",
1102 | "c.head(1)\n",
1103 | "# Diet Coke 159"
1104 | ]
1105 | }
1106 | ],
1107 | "metadata": {
1108 | "anaconda-cloud": {},
1109 | "celltoolbar": "Slideshow",
1110 | "kernelspec": {
1111 | "display_name": "Python 2",
1112 | "language": "python",
1113 | "name": "python2"
1114 | },
1115 | "language_info": {
1116 | "codemirror_mode": {
1117 | "name": "ipython",
1118 | "version": 2
1119 | },
1120 | "file_extension": ".py",
1121 | "mimetype": "text/x-python",
1122 | "name": "python",
1123 | "nbconvert_exporter": "python",
1124 | "pygments_lexer": "ipython2",
1125 | "version": "2.7.14"
1126 | }
1127 | },
1128 | "nbformat": 4,
1129 | "nbformat_minor": 1
1130 | }
1131 |
--------------------------------------------------------------------------------
/Clase 3/03_Groupping_&_Apply-Estudiantes.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "slideshow": {
7 | "slide_type": "slide"
8 | }
9 | },
10 | "source": [
11 | "\n",
12 | " \n",
13 | "\n",
14 | " \n",
15 | "\n",
16 | "# Taller de Manejo y Visualización de Datos con Python\n",
17 | "### Grouping & Apply \n",
18 | "\n",
19 | "Felipe González P. \n",
20 | "felipe.gonzalezp.12@sansano.usm.cl \n",
21 | "\n",
22 | "*Agradecimientos a : https://github.com/justmarkham* \n",
23 | "\n",
24 | "\n",
25 | "\n",
26 | "\n"
27 | ]
28 | },
29 | {
30 | "cell_type": "markdown",
31 | "metadata": {
32 | "slideshow": {
33 | "slide_type": "slide"
34 | }
35 | },
36 | "source": [
37 | "# Dataframe\n",
38 | "\n",
39 | "Es una estructura de datos bidimensional (lo datos se alinean de forma tabular en filas y columnas).\n",
40 | "\n",
41 | "**Ventajas:**\n",
42 | "* Las columnas pueden ser de distinto tipo.\n",
43 | "* El tamaño puede ser mutable.\n",
44 | "* Se pueden acceder a columnas y filas específicas.\n",
45 | "* Se pueden realizar operaciones sobre filas y columnas\n"
46 | ]
47 | },
48 | {
49 | "cell_type": "markdown",
50 | "metadata": {
51 | "slideshow": {
52 | "slide_type": "slide"
53 | }
54 | },
55 | "source": [
56 | " "
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {
62 | "slideshow": {
63 | "slide_type": "slide"
64 | }
65 | },
66 | "source": [
67 | "Un Dataframe puede ser creado a través de los siguientes input:\n",
68 | "* List\n",
69 | "* Dict\n",
70 | "* Series\n",
71 | "* Numpy ndarrays\n",
72 | "* A partir de otro dataframe"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {
78 | "slideshow": {
79 | "slide_type": "slide"
80 | }
81 | },
82 | "source": [
83 | "GroupBy "
84 | ]
85 | },
86 | {
87 | "cell_type": "markdown",
88 | "metadata": {
89 | "slideshow": {
90 | "slide_type": "slide"
91 | }
92 | },
93 | "source": [
94 | "### Introducción:\n",
95 | "\n",
96 | "GroupBy puede ser resumido en un Dividir-Aplicar-Combinar (*Split-Apply-Combine*)\n",
97 | "\n",
98 | "\n"
99 | ]
100 | },
101 | {
102 | "cell_type": "markdown",
103 | "metadata": {
104 | "slideshow": {
105 | "slide_type": "fragment"
106 | }
107 | },
108 | "source": [
109 | "\n"
110 | ]
111 | },
112 | {
113 | "cell_type": "markdown",
114 | "metadata": {
115 | "slideshow": {
116 | "slide_type": "slide"
117 | }
118 | },
119 | "source": [
120 | ""
121 | ]
122 | },
123 | {
124 | "cell_type": "markdown",
125 | "metadata": {
126 | "slideshow": {
127 | "slide_type": "slide"
128 | }
129 | },
130 | "source": [
131 | "# Patrón: Split - Apply - Combine\n",
132 | "\n",
133 | "* Un dataset es dividido en pequeñas partes\n",
134 | "* Cada una de esas piezas es operada/analizada independientemente\n",
135 | "* Todos los resultados son combinados al final. \n",
136 | "\n",
137 | "*Este patrón es similar a MapReduce (modelo de programación para dar soporte a la computación paralela sobre grandes colecciones de datos en grupos de computadoras y al commodity computing.) *"
138 | ]
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {
143 | "slideshow": {
144 | "slide_type": "slide"
145 | }
146 | },
147 | "source": [
148 | " Consumo de alcohol por continente "
149 | ]
150 | },
151 | {
152 | "cell_type": "markdown",
153 | "metadata": {
154 | "slideshow": {
155 | "slide_type": "slide"
156 | }
157 | },
158 | "source": [
159 | "### Importar Librería necesaria"
160 | ]
161 | },
162 | {
163 | "cell_type": "code",
164 | "execution_count": null,
165 | "metadata": {
166 | "slideshow": {
167 | "slide_type": "fragment"
168 | }
169 | },
170 | "outputs": [],
171 | "source": [
172 | "import pandas as pd\n",
173 | "import matplotlib\n",
174 | "%matplotlib inline"
175 | ]
176 | },
177 | {
178 | "cell_type": "markdown",
179 | "metadata": {
180 | "slideshow": {
181 | "slide_type": "slide"
182 | }
183 | },
184 | "source": [
185 | "### Descargar dataset desde [url](https://raw.githubusercontent.com/justmarkham/DAT8/master/data/drinks.csv). "
186 | ]
187 | },
188 | {
189 | "cell_type": "markdown",
190 | "metadata": {
191 | "slideshow": {
192 | "slide_type": "slide"
193 | }
194 | },
195 | "source": [
196 | "### Guardar datos en una variable"
197 | ]
198 | },
199 | {
200 | "cell_type": "code",
201 | "execution_count": null,
202 | "metadata": {
203 | "slideshow": {
204 | "slide_type": "fragment"
205 | }
206 | },
207 | "outputs": [],
208 | "source": [
209 | "drinks = pd.read_csv('https://raw.githubusercontent.com/justmarkham/DAT8/master/data/drinks.csv')\n",
210 | "drinks.head() #asume n igual a 5 en caso de no agregar un valor"
211 | ]
212 | },
213 | {
214 | "cell_type": "markdown",
215 | "metadata": {
216 | "slideshow": {
217 | "slide_type": "slide"
218 | }
219 | },
220 | "source": [
221 | "### ¿Qué continente bebe más cerveza en promedio? ¿Cuál bebe menos?"
222 | ]
223 | },
224 | {
225 | "cell_type": "code",
226 | "execution_count": null,
227 | "metadata": {
228 | "slideshow": {
229 | "slide_type": "fragment"
230 | }
231 | },
232 | "outputs": [],
233 | "source": [
234 | "drinks.groupby('continent').beer_servings.mean()"
235 | ]
236 | },
237 | {
238 | "cell_type": "markdown",
239 | "metadata": {
240 | "slideshow": {
241 | "slide_type": "slide"
242 | }
243 | },
244 | "source": [
245 | "### Imprimir las estadísticas de consumo de vino por cada continente"
246 | ]
247 | },
248 | {
249 | "cell_type": "code",
250 | "execution_count": null,
251 | "metadata": {
252 | "slideshow": {
253 | "slide_type": "fragment"
254 | }
255 | },
256 | "outputs": [],
257 | "source": [
258 | "drinks.groupby('continent').wine_servings.describe()\n"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": null,
264 | "metadata": {
265 | "slideshow": {
266 | "slide_type": "slide"
267 | }
268 | },
269 | "outputs": [],
270 | "source": [
271 | "drinks.groupby('continent').wine_servings.describe().boxplot()\n"
272 | ]
273 | },
274 | {
275 | "cell_type": "markdown",
276 | "metadata": {
277 | "slideshow": {
278 | "slide_type": "slide"
279 | }
280 | },
281 | "source": [
282 | "### ¿Cuál es el promedio de consumo por cada columna en cada continente?"
283 | ]
284 | },
285 | {
286 | "cell_type": "code",
287 | "execution_count": null,
288 | "metadata": {
289 | "slideshow": {
290 | "slide_type": "fragment"
291 | }
292 | },
293 | "outputs": [],
294 | "source": [
295 | "drinks.groupby('continent').mean()"
296 | ]
297 | },
298 | {
299 | "cell_type": "markdown",
300 | "metadata": {
301 | "slideshow": {
302 | "slide_type": "slide"
303 | }
304 | },
305 | "source": [
306 | "### ¿Cuál es la mediana de consumo por cada columna en cada continente?\n"
307 | ]
308 | },
309 | {
310 | "cell_type": "code",
311 | "execution_count": null,
312 | "metadata": {
313 | "slideshow": {
314 | "slide_type": "fragment"
315 | }
316 | },
317 | "outputs": [],
318 | "source": [
319 | "drinks.groupby('continent').median()"
320 | ]
321 | },
322 | {
323 | "cell_type": "markdown",
324 | "metadata": {
325 | "slideshow": {
326 | "slide_type": "slide"
327 | }
328 | },
329 | "source": [
330 | "### Imprimir el promedio, mínimo y máximo con respecto al consumo de *spirit* agrupado por continente"
331 | ]
332 | },
333 | {
334 | "cell_type": "code",
335 | "execution_count": null,
336 | "metadata": {
337 | "slideshow": {
338 | "slide_type": "fragment"
339 | }
340 | },
341 | "outputs": [],
342 | "source": [
343 | "drinks.groupby('continent').spirit_servings.agg(['mean', 'min', 'max']) #llama a la funcion mean, min, max\n"
344 | ]
345 | },
346 | {
347 | "cell_type": "markdown",
348 | "metadata": {
349 | "slideshow": {
350 | "slide_type": "slide"
351 | }
352 | },
353 | "source": [
354 | "Apply "
355 | ]
356 | },
357 | {
358 | "cell_type": "markdown",
359 | "metadata": {
360 | "slideshow": {
361 | "slide_type": "slide"
362 | }
363 | },
364 | "source": [
365 | " Consumo de alcohol en estudiantes "
366 | ]
367 | },
368 | {
369 | "cell_type": "markdown",
370 | "metadata": {
371 | "slideshow": {
372 | "slide_type": "slide"
373 | }
374 | },
375 | "source": [
376 | "### Los datos necesarios están aqui: [url](https://github.com/guipsamora/pandas_exercises/blob/master/04_Apply/Students_Alcohol_Consumption/student-mat.csv).\n",
377 | "\n",
378 | "### Lo guardaremos como siempre en una variable"
379 | ]
380 | },
381 | {
382 | "cell_type": "code",
383 | "execution_count": null,
384 | "metadata": {
385 | "slideshow": {
386 | "slide_type": "fragment"
387 | }
388 | },
389 | "outputs": [],
390 | "source": [
391 | "df = pd.read_csv('https://raw.githubusercontent.com/guipsamora/pandas_exercises/master/04_Apply/Students_Alcohol_Consumption/student-mat.csv', sep = ',')\n",
392 | "df.head()"
393 | ]
394 | },
395 | {
396 | "cell_type": "markdown",
397 | "metadata": {
398 | "slideshow": {
399 | "slide_type": "slide"
400 | }
401 | },
402 | "source": [
403 | "### ¡Son muchas columnas! Solo queremos las que están dentro del rango [school,guardian]"
404 | ]
405 | },
406 | {
407 | "cell_type": "code",
408 | "execution_count": null,
409 | "metadata": {
410 | "slideshow": {
411 | "slide_type": "fragment"
412 | }
413 | },
414 | "outputs": [],
415 | "source": [
416 | "stud_alcoh = df.loc[: , \"school\":\"guardian\"] # es para seleccionar. df.loc[row_indexer,column_indexer]\n",
417 | "stud_alcoh.head()"
418 | ]
419 | },
420 | {
421 | "cell_type": "markdown",
422 | "metadata": {
423 | "slideshow": {
424 | "slide_type": "slide"
425 | }
426 | },
427 | "source": [
428 | "### Creemos una función que ponga en mayúscula ciertas palabras"
429 | ]
430 | },
431 | {
432 | "cell_type": "code",
433 | "execution_count": null,
434 | "metadata": {
435 | "slideshow": {
436 | "slide_type": "fragment"
437 | }
438 | },
439 | "outputs": [],
440 | "source": [
441 | "captalizer = lambda x: x.upper()"
442 | ]
443 | },
444 | {
445 | "cell_type": "markdown",
446 | "metadata": {
447 | "slideshow": {
448 | "slide_type": "slide"
449 | }
450 | },
451 | "source": [
452 | "### Pongamos en mayúsculas Mjob y Fjob"
453 | ]
454 | },
455 | {
456 | "cell_type": "code",
457 | "execution_count": null,
458 | "metadata": {
459 | "slideshow": {
460 | "slide_type": "fragment"
461 | }
462 | },
463 | "outputs": [],
464 | "source": [
465 | "stud_alcoh['Mjob'].apply(captalizer)\n",
466 | "stud_alcoh['Fjob'].apply(captalizer)"
467 | ]
468 | },
469 | {
470 | "cell_type": "markdown",
471 | "metadata": {
472 | "slideshow": {
473 | "slide_type": "slide"
474 | }
475 | },
476 | "source": [
477 | "### ¿Cuáles son los últimos 5 elementos del dataset?"
478 | ]
479 | },
480 | {
481 | "cell_type": "code",
482 | "execution_count": null,
483 | "metadata": {
484 | "slideshow": {
485 | "slide_type": "fragment"
486 | }
487 | },
488 | "outputs": [],
489 | "source": [
490 | "stud_alcoh.tail() #Por defecto n = 5"
491 | ]
492 | },
493 | {
494 | "cell_type": "markdown",
495 | "metadata": {
496 | "slideshow": {
497 | "slide_type": "slide"
498 | }
499 | },
500 | "source": [
501 | "### ¡El dataset original aún tiene en minúsculas Mjob y Fjob!"
502 | ]
503 | },
504 | {
505 | "cell_type": "code",
506 | "execution_count": null,
507 | "metadata": {
508 | "slideshow": {
509 | "slide_type": "fragment"
510 | }
511 | },
512 | "outputs": [],
513 | "source": [
514 | "stud_alcoh['Mjob'] = stud_alcoh['Mjob'].apply(captalizer)\n",
515 | "stud_alcoh['Fjob'] = stud_alcoh['Fjob'].apply(captalizer)\n",
516 | "stud_alcoh.tail()"
517 | ]
518 | },
519 | {
520 | "cell_type": "markdown",
521 | "metadata": {
522 | "slideshow": {
523 | "slide_type": "slide"
524 | }
525 | },
526 | "source": [
527 | "### Creemos una nueva columna que muestre 'true' en el caso de que el individuo sea un *legal_drinker*"
528 | ]
529 | },
530 | {
531 | "cell_type": "code",
532 | "execution_count": null,
533 | "metadata": {
534 | "slideshow": {
535 | "slide_type": "fragment"
536 | }
537 | },
538 | "outputs": [],
539 | "source": [
540 | "def majority(x):\n",
541 | " if x > 17:\n",
542 | " return True\n",
543 | " else:\n",
544 | " return False"
545 | ]
546 | },
547 | {
548 | "cell_type": "code",
549 | "execution_count": null,
550 | "metadata": {
551 | "slideshow": {
552 | "slide_type": "slide"
553 | }
554 | },
555 | "outputs": [],
556 | "source": [
557 | "stud_alcoh['legal_drinker'] = stud_alcoh['age'].apply(majority)\n",
558 | "stud_alcoh.head()"
559 | ]
560 | },
561 | {
562 | "cell_type": "markdown",
563 | "metadata": {
564 | "slideshow": {
565 | "slide_type": "slide"
566 | }
567 | },
568 | "source": [
569 | "### Multipliquemos cada número del dataset por 10\n",
570 | ""
571 | ]
572 | },
573 | {
574 | "cell_type": "code",
575 | "execution_count": null,
576 | "metadata": {
577 | "slideshow": {
578 | "slide_type": "slide"
579 | }
580 | },
581 | "outputs": [],
582 | "source": [
583 | "import numpy \n",
584 | "def times10(x):\n",
585 | " if type(x) is long:\n",
586 | " return 10*x\n",
587 | " else:\n",
588 | " return x\n"
589 | ]
590 | },
591 | {
592 | "cell_type": "code",
593 | "execution_count": null,
594 | "metadata": {
595 | "slideshow": {
596 | "slide_type": "slide"
597 | }
598 | },
599 | "outputs": [],
600 | "source": [
601 | "stud_alcoh.applymap(times10).head(10)\n",
602 | "#Applymap: Apply a function to a DataFrame that is intended to operate elementwise, \n",
603 | "#i.e. like doing map(func, series) for each series in the DataFrame"
604 | ]
605 | },
606 | {
607 | "cell_type": "markdown",
608 | "metadata": {
609 | "slideshow": {
610 | "slide_type": "slide"
611 | }
612 | },
613 | "source": [
614 | "Ejercicios "
615 | ]
616 | },
617 | {
618 | "cell_type": "markdown",
619 | "metadata": {
620 | "slideshow": {
621 | "slide_type": "slide"
622 | }
623 | },
624 | "source": [
625 | "### Ocupar los datos de: [url](https://raw.githubusercontent.com/justmarkham/DAT8/master/data/u.user) y guardarlos en una variable. "
626 | ]
627 | },
628 | {
629 | "cell_type": "code",
630 | "execution_count": null,
631 | "metadata": {
632 | "slideshow": {
633 | "slide_type": "fragment"
634 | }
635 | },
636 | "outputs": [],
637 | "source": [
638 | "\n"
639 | ]
640 | },
641 | {
642 | "cell_type": "markdown",
643 | "metadata": {
644 | "slideshow": {
645 | "slide_type": "slide"
646 | }
647 | },
648 | "source": [
649 | "### Muestra las primeros 5 filas del dataset"
650 | ]
651 | },
652 | {
653 | "cell_type": "code",
654 | "execution_count": null,
655 | "metadata": {
656 | "slideshow": {
657 | "slide_type": "fragment"
658 | }
659 | },
660 | "outputs": [],
661 | "source": []
662 | },
663 | {
664 | "cell_type": "markdown",
665 | "metadata": {
666 | "slideshow": {
667 | "slide_type": "slide"
668 | }
669 | },
670 | "source": [
671 | "### ¿Cuál es la media de edad por ocupación?"
672 | ]
673 | },
674 | {
675 | "cell_type": "code",
676 | "execution_count": null,
677 | "metadata": {
678 | "slideshow": {
679 | "slide_type": "fragment"
680 | }
681 | },
682 | "outputs": [],
683 | "source": []
684 | },
685 | {
686 | "cell_type": "markdown",
687 | "metadata": {
688 | "slideshow": {
689 | "slide_type": "slide"
690 | }
691 | },
692 | "source": [
693 | "### Descubre la proporción de hombres por ocupación y ordenalos de mayor a menor"
694 | ]
695 | },
696 | {
697 | "cell_type": "code",
698 | "execution_count": null,
699 | "metadata": {
700 | "slideshow": {
701 | "slide_type": "fragment"
702 | }
703 | },
704 | "outputs": [],
705 | "source": []
706 | },
707 | {
708 | "cell_type": "markdown",
709 | "metadata": {
710 | "slideshow": {
711 | "slide_type": "slide"
712 | }
713 | },
714 | "source": [
715 | "### Por cada ocupación calcula el mínimo y máximo valor"
716 | ]
717 | },
718 | {
719 | "cell_type": "code",
720 | "execution_count": null,
721 | "metadata": {
722 | "slideshow": {
723 | "slide_type": "fragment"
724 | }
725 | },
726 | "outputs": [],
727 | "source": []
728 | },
729 | {
730 | "cell_type": "markdown",
731 | "metadata": {
732 | "slideshow": {
733 | "slide_type": "slide"
734 | }
735 | },
736 | "source": [
737 | "### Por cada combinación \"ocupación-genero\" calcula el promedio de la edad"
738 | ]
739 | },
740 | {
741 | "cell_type": "code",
742 | "execution_count": null,
743 | "metadata": {
744 | "slideshow": {
745 | "slide_type": "fragment"
746 | }
747 | },
748 | "outputs": [],
749 | "source": []
750 | },
751 | {
752 | "cell_type": "markdown",
753 | "metadata": {
754 | "slideshow": {
755 | "slide_type": "slide"
756 | }
757 | },
758 | "source": [
759 | "### Por cada ocupación muestra el porcentaje de hombres y mujeres"
760 | ]
761 | },
762 | {
763 | "cell_type": "code",
764 | "execution_count": null,
765 | "metadata": {
766 | "slideshow": {
767 | "slide_type": "fragment"
768 | }
769 | },
770 | "outputs": [],
771 | "source": []
772 | },
773 | {
774 | "cell_type": "markdown",
775 | "metadata": {
776 | "slideshow": {
777 | "slide_type": "slide"
778 | }
779 | },
780 | "source": [
781 | "# Consumo de alcohol en estudiantes"
782 | ]
783 | },
784 | {
785 | "cell_type": "markdown",
786 | "metadata": {
787 | "slideshow": {
788 | "slide_type": "slide"
789 | }
790 | },
791 | "source": [
792 | "### Los datos son los siguientes"
793 | ]
794 | },
795 | {
796 | "cell_type": "code",
797 | "execution_count": 1,
798 | "metadata": {
799 | "slideshow": {
800 | "slide_type": "fragment"
801 | }
802 | },
803 | "outputs": [],
804 | "source": [
805 | "raw_data = {'regiment': ['Nighthawks', 'Nighthawks', 'Nighthawks', 'Nighthawks', 'Dragoons', 'Dragoons', 'Dragoons', 'Dragoons', 'Scouts', 'Scouts', 'Scouts', 'Scouts'], \n",
806 | " 'company': ['1st', '1st', '2nd', '2nd', '1st', '1st', '2nd', '2nd','1st', '1st', '2nd', '2nd'], \n",
807 | " 'name': ['Miller', 'Jacobson', 'Ali', 'Milner', 'Cooze', 'Jacon', 'Ryaner', 'Sone', 'Sloan', 'Piger', 'Riani', 'Ali'], \n",
808 | " 'preTestScore': [4, 24, 31, 2, 3, 4, 24, 31, 2, 3, 2, 3],\n",
809 | " 'postTestScore': [25, 94, 57, 62, 70, 25, 94, 57, 62, 70, 62, 70]}"
810 | ]
811 | },
812 | {
813 | "cell_type": "markdown",
814 | "metadata": {
815 | "slideshow": {
816 | "slide_type": "slide"
817 | }
818 | },
819 | "source": [
820 | "### Convierte el diccionario en un dataframe"
821 | ]
822 | },
823 | {
824 | "cell_type": "code",
825 | "execution_count": null,
826 | "metadata": {
827 | "slideshow": {
828 | "slide_type": "fragment"
829 | }
830 | },
831 | "outputs": [],
832 | "source": []
833 | },
834 | {
835 | "cell_type": "markdown",
836 | "metadata": {
837 | "slideshow": {
838 | "slide_type": "slide"
839 | }
840 | },
841 | "source": [
842 | "### ¿Cual es el promedio de el preTestScore del regimiento Nighthawks?"
843 | ]
844 | },
845 | {
846 | "cell_type": "code",
847 | "execution_count": null,
848 | "metadata": {
849 | "slideshow": {
850 | "slide_type": "fragment"
851 | }
852 | },
853 | "outputs": [],
854 | "source": []
855 | },
856 | {
857 | "cell_type": "markdown",
858 | "metadata": {
859 | "slideshow": {
860 | "slide_type": "slide"
861 | }
862 | },
863 | "source": [
864 | "### Muestra estadíticas generales por compañia"
865 | ]
866 | },
867 | {
868 | "cell_type": "code",
869 | "execution_count": null,
870 | "metadata": {
871 | "slideshow": {
872 | "slide_type": "fragment"
873 | }
874 | },
875 | "outputs": [],
876 | "source": []
877 | },
878 | {
879 | "cell_type": "markdown",
880 | "metadata": {
881 | "slideshow": {
882 | "slide_type": "slide"
883 | }
884 | },
885 | "source": [
886 | "### ¿Cual es el promedio para cada compañía en el preTestScore?\n"
887 | ]
888 | },
889 | {
890 | "cell_type": "code",
891 | "execution_count": null,
892 | "metadata": {
893 | "slideshow": {
894 | "slide_type": "fragment"
895 | }
896 | },
897 | "outputs": [],
898 | "source": []
899 | },
900 | {
901 | "cell_type": "markdown",
902 | "metadata": {
903 | "slideshow": {
904 | "slide_type": "slide"
905 | }
906 | },
907 | "source": [
908 | "### Mostrar el promedio en el preTestScore segun regiment y company\n"
909 | ]
910 | },
911 | {
912 | "cell_type": "code",
913 | "execution_count": null,
914 | "metadata": {
915 | "slideshow": {
916 | "slide_type": "fragment"
917 | }
918 | },
919 | "outputs": [],
920 | "source": []
921 | },
922 | {
923 | "cell_type": "markdown",
924 | "metadata": {
925 | "slideshow": {
926 | "slide_type": "slide"
927 | }
928 | },
929 | "source": [
930 | "### Agrupar todo el dataframe por regimiento y compañía, de tal forma que se vea esto:\n",
931 | " \n"
932 | ]
933 | },
934 | {
935 | "cell_type": "code",
936 | "execution_count": null,
937 | "metadata": {
938 | "slideshow": {
939 | "slide_type": "fragment"
940 | }
941 | },
942 | "outputs": [],
943 | "source": []
944 | },
945 | {
946 | "cell_type": "markdown",
947 | "metadata": {
948 | "slideshow": {
949 | "slide_type": "slide"
950 | }
951 | },
952 | "source": [
953 | "### ¿Cuál es el número de observaciones en cada regimiento y compañía?"
954 | ]
955 | },
956 | {
957 | "cell_type": "code",
958 | "execution_count": null,
959 | "metadata": {
960 | "slideshow": {
961 | "slide_type": "fragment"
962 | }
963 | },
964 | "outputs": [],
965 | "source": []
966 | },
967 | {
968 | "cell_type": "markdown",
969 | "metadata": {
970 | "slideshow": {
971 | "slide_type": "slide"
972 | }
973 | },
974 | "source": [
975 | "### Itera sobre cada regimiento de tal forma que puedas imprimir por pantalla toda su información:"
976 | ]
977 | },
978 | {
979 | "cell_type": "markdown",
980 | "metadata": {
981 | "slideshow": {
982 | "slide_type": "fragment"
983 | }
984 | },
985 | "source": [
986 | " "
987 | ]
988 | },
989 | {
990 | "cell_type": "code",
991 | "execution_count": null,
992 | "metadata": {
993 | "slideshow": {
994 | "slide_type": "slide"
995 | }
996 | },
997 | "outputs": [],
998 | "source": []
999 | }
1000 | ],
1001 | "metadata": {
1002 | "anaconda-cloud": {},
1003 | "celltoolbar": "Slideshow",
1004 | "kernelspec": {
1005 | "display_name": "Python 2",
1006 | "language": "python",
1007 | "name": "python2"
1008 | },
1009 | "language_info": {
1010 | "codemirror_mode": {
1011 | "name": "ipython",
1012 | "version": 2
1013 | },
1014 | "file_extension": ".py",
1015 | "mimetype": "text/x-python",
1016 | "name": "python",
1017 | "nbconvert_exporter": "python",
1018 | "pygments_lexer": "ipython2",
1019 | "version": "2.7.14"
1020 | }
1021 | },
1022 | "nbformat": 4,
1023 | "nbformat_minor": 1
1024 | }
1025 |
--------------------------------------------------------------------------------
/Clase 3/grouping.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 3/grouping.png
--------------------------------------------------------------------------------
/Clase 3/grouping2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 3/grouping2.png
--------------------------------------------------------------------------------
/Clase 4/matplotlib.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 4/matplotlib.png
--------------------------------------------------------------------------------
/Clase 4/seaborn.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 4/seaborn.png
--------------------------------------------------------------------------------
/Clase 5/Introducción a MatplotLib-Formato Estudiantes.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "slideshow": {
7 | "slide_type": "slide"
8 | }
9 | },
10 | "source": [
11 | "\n",
12 | " \n",
13 | "\n",
14 | " \n",
15 | "\n",
16 | "# Taller de Manejo y Visualización de Datos con Python\n",
17 | "Introducción a Matplotlib \n",
18 | "Felipe González P. \n",
19 | "felipe.gonzalezp.12@sansano.usm.cl \n",
20 | "\n",
21 | " \n",
22 | "Jueves Bloque 7-8 \n",
23 | "Campus San Joaquín\n",
24 | "\n",
25 | "\n"
26 | ]
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "metadata": {
31 | "slideshow": {
32 | "slide_type": "slide"
33 | }
34 | },
35 | "source": [
36 | "## Introducción\n",
37 | "\n",
38 | "Matplotlib es probablemente el paquete de Python más utilizado para gráficos 2D. Proporciona una forma muy rápida de visualizar datos de Python y cifras de calidad de publicación en muchos formatos. "
39 | ]
40 | },
41 | {
42 | "cell_type": "markdown",
43 | "metadata": {},
44 | "source": [
45 | "## Que debemos hacer\n",
46 | "\n",
47 | "Siempre que trabajemos en un IPython notebook debemos escribir:"
48 | ]
49 | },
50 | {
51 | "cell_type": "code",
52 | "execution_count": null,
53 | "metadata": {},
54 | "outputs": [],
55 | "source": [
56 | "%matplotlib inline\n"
57 | ]
58 | },
59 | {
60 | "cell_type": "markdown",
61 | "metadata": {},
62 | "source": [
63 | "## Importar Matplotlib"
64 | ]
65 | },
66 | {
67 | "cell_type": "code",
68 | "execution_count": null,
69 | "metadata": {},
70 | "outputs": [],
71 | "source": [
72 | "from matplotlib import pyplot as plt\n"
73 | ]
74 | },
75 | {
76 | "cell_type": "markdown",
77 | "metadata": {},
78 | "source": [
79 | "## Figura\n",
80 | ""
81 | ]
82 | },
83 | {
84 | "cell_type": "markdown",
85 | "metadata": {},
86 | "source": [
87 | "## Figures, Subplots, Axes and Ticks\n",
88 | "\n",
89 | "*Una 'figure' en matplotlib significa la ventana completa de la interfaz. Dentro de esta figura pueden haber 'subplots'\n",
90 | "\n",
91 | "Podemos tener el control sobre lo mostrado utilizando 'figure', 'subplot' y 'axes' de manera específica. Mientras 'subplot' es utilizado para añadir pequeñas figuras dentro de una grilla, 'axes' permite tener mayor control de lo programado. \n",
92 | "\n",
93 | "Importante: \n",
94 | "*gca()* se utiliza para obtener los 'axes' actuales \n",
95 | "*gcf()* se utiliza para obtener la figura actual. "
96 | ]
97 | },
98 | {
99 | "cell_type": "markdown",
100 | "metadata": {},
101 | "source": [
102 | "## Figures \n",
103 | " \n",
104 | ""
105 | ]
106 | },
107 | {
108 | "cell_type": "markdown",
109 | "metadata": {},
110 | "source": [
111 | "## Subplots\n",
112 | "\n",
113 | "Se puede ocupar subplot(fila,columna,indice) o 'gridspec' en caso de querer algo más poderoso\n",
114 | "\n",
115 | ""
116 | ]
117 | },
118 | {
119 | "cell_type": "markdown",
120 | "metadata": {},
121 | "source": [
122 | "## Axes\n",
123 | "Los ejes (*axes*) son muy similares a las subplots, pero permiten la colocación de gráficos en cualquier ubicación de la figura. Entonces, si queremos poner una gráfico más pequeño dentro de uno más grande, lo hacemos con *axes*.\n",
124 | "\n",
125 | ""
126 | ]
127 | },
128 | {
129 | "cell_type": "markdown",
130 | "metadata": {},
131 | "source": [
132 | "## Ticks\n",
133 | " \n",
134 | ""
135 | ]
136 | },
137 | {
138 | "cell_type": "markdown",
139 | "metadata": {},
140 | "source": [
141 | "## Datos\n",
142 | "\n",
143 | "Misión: Dibujar las funciones de coseno y seno en la misma figura. \n",
144 | "\n",
145 | "El primer paso es obtener los datos para las funciones seno y coseno:"
146 | ]
147 | },
148 | {
149 | "cell_type": "code",
150 | "execution_count": null,
151 | "metadata": {},
152 | "outputs": [],
153 | "source": [
154 | "import numpy as np\n",
155 | "\n",
156 | "X = np.linspace(-np.pi, np.pi, 256, endpoint=True) #valores x (256 valores)\n",
157 | "C, S = np.cos(X), np.sin(X) # valores y de seno y coseno"
158 | ]
159 | },
160 | {
161 | "cell_type": "markdown",
162 | "metadata": {},
163 | "source": [
164 | "### Gráfico Simple\n",
165 | "\n",
166 | "Matplotlib viene con un conjunto de configuraciones predeterminadas que permiten personalizar todo tipo de propiedades. Se puede controlar los valores predeterminados de casi todas las propiedades en matplotlib: tamaño de figura, ancho de línea, color y estilo, ejes, propiedades de cuadrícula, propiedades de texto, etc."
167 | ]
168 | },
169 | {
170 | "cell_type": "code",
171 | "execution_count": null,
172 | "metadata": {},
173 | "outputs": [],
174 | "source": [
175 | "import numpy as np\n",
176 | "import matplotlib.pyplot as plt\n",
177 | "\n",
178 | "X = np.linspace(-np.pi, np.pi, 256, endpoint=True)\n",
179 | "C, S = np.cos(X), np.sin(X)\n",
180 | "\n",
181 | "plt.plot(X, C)\n",
182 | "plt.plot(X, S)\n",
183 | "\n",
184 | "plt.show()"
185 | ]
186 | },
187 | {
188 | "cell_type": "markdown",
189 | "metadata": {},
190 | "source": [
191 | "## ¿Qué valores podemos cambiar?"
192 | ]
193 | },
194 | {
195 | "cell_type": "code",
196 | "execution_count": null,
197 | "metadata": {},
198 | "outputs": [],
199 | "source": [
200 | "import numpy as np\n",
201 | "import matplotlib.pyplot as plt\n",
202 | "\n",
203 | "#Crear una figura de 8x6 pulgadas, 80 puntos por pulgada.\n",
204 | "plt.figure(figsize=(8, 6), dpi=80)\n",
205 | "\n",
206 | "# Crear un nuevo subplot desde una grilla de 1 por 1\n",
207 | "plt.subplot(1, 1, 1) #fila, columna, indice\n",
208 | "\n",
209 | "#datos\n",
210 | "X = np.linspace(-np.pi, np.pi, 256, endpoint=True)\n",
211 | "C, S = np.cos(X), np.sin(X)\n",
212 | "\n",
213 | "#Graficar cosino con una linea azul continua de ancho 1 (pixeles)\n",
214 | "plt.plot(X, C, color=\"blue\", linewidth=1.0, linestyle=\"-\")\n",
215 | "\n",
216 | "plt.plot(X, S, color=\"green\", linewidth=1.0, linestyle=\"-\")\n",
217 | "\n",
218 | "# Establecer x limites\n",
219 | "plt.xlim(-4.0, 4.0)\n",
220 | "\n",
221 | "plt.xticks(np.linspace(-4, 4, 9, endpoint=True)) #parametros de eje x\n",
222 | "\n",
223 | "# Establecer y limites\n",
224 | "plt.ylim(-1.0, 1.0)\n",
225 | "\n",
226 | "plt.yticks(np.linspace(-1, 1, 5, endpoint=True)) #parametro de eje y\n",
227 | "\n",
228 | "# Guardar figura usando 72 puntos por pulgada\n",
229 | "# plt.savefig(\"ejercicio_2.png\", dpi=72)\n",
230 | "\n",
231 | "# Mostrar resultado en pantalla\n",
232 | "plt.show()"
233 | ]
234 | },
235 | {
236 | "cell_type": "markdown",
237 | "metadata": {},
238 | "source": [
239 | "## Cambiar colores y ancho de lineas"
240 | ]
241 | },
242 | {
243 | "cell_type": "code",
244 | "execution_count": null,
245 | "metadata": {},
246 | "outputs": [],
247 | "source": [
248 | "plt.figure(figsize=(10, 6), dpi=80)\n",
249 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\")\n",
250 | "plt.plot(X, S, color=\"red\", linewidth=5.5, linestyle=\"-\")"
251 | ]
252 | },
253 | {
254 | "cell_type": "markdown",
255 | "metadata": {},
256 | "source": [
257 | "## Establecer límites\n",
258 | "Debemos cambiar los límites de la figura para que toda la data calce en ella"
259 | ]
260 | },
261 | {
262 | "cell_type": "code",
263 | "execution_count": null,
264 | "metadata": {},
265 | "outputs": [],
266 | "source": [
267 | "plt.figure(figsize=(10, 6), dpi=80)\n",
268 | "plt.xlim(X.min() * 1.1, X.max() * 1.2)\n",
269 | "plt.ylim(C.min() * 1.1, C.max() * 1.2)\n",
270 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\")\n",
271 | "plt.plot(X, S, color=\"red\", linewidth=2.5, linestyle=\"-\")"
272 | ]
273 | },
274 | {
275 | "cell_type": "markdown",
276 | "metadata": {},
277 | "source": [
278 | "## Establecer etiquetas\n",
279 | "\n",
280 | "Las marcas actuales no son ideales porque no muestran los valores interesantes (+/- π, + / - π / 2) para el seno y el coseno. Los cambiaremos de modo que solo muestren estos valores."
281 | ]
282 | },
283 | {
284 | "cell_type": "code",
285 | "execution_count": null,
286 | "metadata": {},
287 | "outputs": [],
288 | "source": [
289 | "plt.figure(figsize=(10, 6), dpi=80)\n",
290 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\")\n",
291 | "plt.plot(X, S, color=\"red\", linewidth=2.5, linestyle=\"-\")\n",
292 | "plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi]) #estan transformados en decimal\n",
293 | "plt.yticks([-1, 0, +1])\n",
294 | "plt.show()"
295 | ]
296 | },
297 | {
298 | "cell_type": "markdown",
299 | "metadata": {},
300 | "source": [
301 | "## Establecer etiquetas\n",
302 | "\n",
303 | "Las marcas ahora están colocadas correctamente, pero su etiqueta no es muy explícita. Podríamos suponer que 3.142 es π, pero sería mejor hacerlo explícito. Cuando establecemos valores de marca, también podemos proporcionar una etiqueta correspondiente en la segunda lista de argumentos. \n",
304 | "\n",
305 | "**Usaremos latex para permitir una buena representación de la etiqueta.**"
306 | ]
307 | },
308 | {
309 | "cell_type": "code",
310 | "execution_count": null,
311 | "metadata": {},
312 | "outputs": [],
313 | "source": [
314 | "plt.figure(figsize=(10, 6), dpi=80)\n",
315 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\")\n",
316 | "plt.plot(X, S, color=\"red\", linewidth=2.5, linestyle=\"-\")\n",
317 | "plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],\n",
318 | " [r'$-\\pi$', r'$-\\pi/2$', r'$0$', r'$+\\pi/2$', r'$+\\pi$'])\n",
319 | "\n",
320 | "plt.yticks([-1, 0, +1],\n",
321 | " [r'$-1$', r'$0$', r'$+1$'])\n",
322 | "plt.show()"
323 | ]
324 | },
325 | {
326 | "cell_type": "markdown",
327 | "metadata": {},
328 | "source": [
329 | "## Modificar marco de la figura\n",
330 | "*Spines* son las líneas que conectan las marcas de eje y anotan los límites del área de datos. Se pueden colocar en posiciones arbitrarias y hasta ahora, estaban en el borde del eje. \n",
331 | "\n",
332 | "Cambiaremos eso ya que queremos tenerlos en el medio. Como hay cuatro (arriba / abajo / izquierda / derecha), descartaremos la parte superior y la derecha configurando el color en 'none' y moveremos el inferior y el izquierdo para centrarlos en 0."
333 | ]
334 | },
335 | {
336 | "cell_type": "code",
337 | "execution_count": null,
338 | "metadata": {},
339 | "outputs": [],
340 | "source": [
341 | "plt.figure(figsize=(10, 6), dpi=80)\n",
342 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\")\n",
343 | "plt.plot(X, S, color=\"red\", linewidth=2.5, linestyle=\"-\")\n",
344 | "plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],\n",
345 | " [r'$-\\pi$', r'$-\\pi/2$', r'$0$', r'$+\\pi/2$', r'$+\\pi$'])\n",
346 | "\n",
347 | "plt.yticks([-1, 0, +1],\n",
348 | " [r'$-1$', r'$0$', r'$+1$'])\n",
349 | "ax = plt.gca() # gca se ocupa para decir q nos referimos al grafico actual\n",
350 | "ax.spines['right'].set_color('none')\n",
351 | "ax.spines['top'].set_color('none')\n",
352 | "ax.xaxis.set_ticks_position('bottom')\n",
353 | "ax.spines['bottom'].set_position(('data',0))\n",
354 | "ax.yaxis.set_ticks_position('left')\n",
355 | "ax.spines['left'].set_position(('data',0)) #outward, axes, data\n",
356 | "plt.show()"
357 | ]
358 | },
359 | {
360 | "cell_type": "markdown",
361 | "metadata": {},
362 | "source": [
363 | "## Añadir una leyenda"
364 | ]
365 | },
366 | {
367 | "cell_type": "code",
368 | "execution_count": null,
369 | "metadata": {},
370 | "outputs": [],
371 | "source": [
372 | "plt.figure(figsize=(10, 6), dpi=80)\n",
373 | "\n",
374 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\", label=\"coseno\")\n",
375 | "plt.plot(X, S, color=\"red\", linewidth=2.5, linestyle=\"-\", label=\"seno\")\n",
376 | "plt.legend(loc='upper left')\n",
377 | "\n",
378 | "\n",
379 | "\n",
380 | "plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],\n",
381 | " [r'$-\\pi$', r'$-\\pi/2$', r'$0$', r'$+\\pi/2$', r'$+\\pi$'])\n",
382 | "plt.yticks([-1, 0, +1],\n",
383 | " [r'$-1$', r'$0$', r'$+1$'])\n",
384 | "ax = plt.gca() # gca se ocupa para decir q nos referimos al grafico actual\n",
385 | "ax.spines['right'].set_color('none')\n",
386 | "ax.spines['top'].set_color('none')\n",
387 | "ax.xaxis.set_ticks_position('bottom')\n",
388 | "ax.spines['bottom'].set_position(('data',0))\n",
389 | "ax.yaxis.set_ticks_position('left')\n",
390 | "ax.spines['left'].set_position(('data',0)) #outward, axes, data\n",
391 | "\n",
392 | "\n",
393 | "plt.show()"
394 | ]
395 | },
396 | {
397 | "cell_type": "markdown",
398 | "metadata": {},
399 | "source": [
400 | "## Indicar puntos específicos\n",
401 | "\n",
402 | "Anotemos algunos puntos interesantes usando el comando *annotate*.\n"
403 | ]
404 | },
405 | {
406 | "cell_type": "code",
407 | "execution_count": null,
408 | "metadata": {},
409 | "outputs": [],
410 | "source": [
411 | "plt.figure(figsize=(10, 6), dpi=80)\n",
412 | "\n",
413 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\", label=\"coseno\")\n",
414 | "plt.plot(X, S, color=\"red\", linewidth=2.5, linestyle=\"-\", label=\"seno\")\n",
415 | "plt.legend(loc='upper left')\n",
416 | "\n",
417 | "t = 2 * np.pi / 3\n",
418 | "plt.plot([t, t], [0, np.cos(t)], color='blue', linewidth=2.5, linestyle=\"--\")\n",
419 | "plt.scatter([t, ], [np.cos(t), ], 50, color='blue')\n",
420 | "\n",
421 | "plt.annotate(r'$sin(\\frac{2\\pi}{3})=\\frac{\\sqrt{3}}{2}$',\n",
422 | " xy=(t, np.sin(t)), xycoords='data',\n",
423 | " xytext=(+10, +30), textcoords='offset points', fontsize=16,\n",
424 | " arrowprops=dict(arrowstyle=\"->\"))\n",
425 | "\n",
426 | "plt.plot([t, t],[0, np.sin(t)], color='red', linewidth=2.5, linestyle=\"--\")\n",
427 | "plt.scatter([t, ],[np.sin(t), ], 50, color='red') #probar eliminar\n",
428 | "\n",
429 | "plt.annotate(r'$cos(\\frac{2\\pi}{3})=-\\frac{1}{2}$',\n",
430 | " xy=(t, np.cos(t)), xycoords='data',\n",
431 | " xytext=(-90, -50), textcoords='offset points', fontsize=16,\n",
432 | " arrowprops=dict(arrowstyle=\"->\"))\n",
433 | "\n",
434 | "plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],\n",
435 | " [r'$-\\pi$', r'$-\\pi/2$', r'$0$', r'$+\\pi/2$', r'$+\\pi$'])\n",
436 | "plt.yticks([-1, 0, +1],\n",
437 | " [r'$-1$', r'$0$', r'$+1$'])\n",
438 | "ax = plt.gca() # gca se ocupa para decir q nos referimos al grafico actual\n",
439 | "ax.spines['right'].set_color('none')\n",
440 | "ax.spines['top'].set_color('none')\n",
441 | "ax.xaxis.set_ticks_position('bottom')\n",
442 | "ax.spines['bottom'].set_position(('data',0))\n",
443 | "ax.yaxis.set_ticks_position('left')\n",
444 | "ax.spines['left'].set_position(('data',0)) #outward, axes, data\n"
445 | ]
446 | },
447 | {
448 | "cell_type": "markdown",
449 | "metadata": {},
450 | "source": [
451 | "## Fijación por los detalles\n",
452 | "\n",
453 | "Las etiquetas están ahora apenas visibles debido a las líneas azul y roja. Podemos hacerlos más grandes y también podemos ajustar sus propiedades de modo que se representen sobre un fondo blanco semitransparente. Esto nos permitirá ver los datos y las etiquetas."
454 | ]
455 | },
456 | {
457 | "cell_type": "code",
458 | "execution_count": null,
459 | "metadata": {},
460 | "outputs": [],
461 | "source": [
462 | "plt.figure(figsize=(10, 6), dpi=80)\n",
463 | "\n",
464 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\", label=\"coseno\")\n",
465 | "plt.plot(X, S, color=\"red\", linewidth=2.5, linestyle=\"-\", label=\"seno\")\n",
466 | "plt.legend(loc='upper left')\n",
467 | "\n",
468 | "t = 2 * np.pi / 3\n",
469 | "plt.plot([t, t], [0, np.cos(t)], color='blue', linewidth=2.5, linestyle=\"--\")\n",
470 | "plt.scatter([t, ], [np.cos(t), ], 50, color='blue')\n",
471 | "\n",
472 | "plt.annotate(r'$sin(\\frac{2\\pi}{3})=\\frac{\\sqrt{3}}{2}$',\n",
473 | " xy=(t, np.sin(t)), xycoords='data',\n",
474 | " xytext=(+10, +30), textcoords='offset points', fontsize=16,\n",
475 | " arrowprops=dict(arrowstyle=\"->\"))\n",
476 | "\n",
477 | "plt.plot([t, t],[0, np.sin(t)], color='red', linewidth=2.5, linestyle=\"--\")\n",
478 | "plt.scatter([t, ],[np.sin(t), ], 50, color='red') #probar eliminar\n",
479 | "\n",
480 | "plt.annotate(r'$cos(\\frac{2\\pi}{3})=-\\frac{1}{2}$',\n",
481 | " xy=(t, np.cos(t)), xycoords='data',\n",
482 | " xytext=(-90, -50), textcoords='offset points', fontsize=16,\n",
483 | " arrowprops=dict(arrowstyle=\"->\"))\n",
484 | "\n",
485 | "plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],\n",
486 | " [r'$-\\pi$', r'$-\\pi/2$', r'$0$', r'$+\\pi/2$', r'$+\\pi$'])\n",
487 | "plt.yticks([-1, 0, +1],\n",
488 | " [r'$-1$', r'$0$', r'$+1$'])\n",
489 | "ax = plt.gca() # gca se ocupa para decir q nos referimos al grafico actual\n",
490 | "ax.spines['right'].set_color('none')\n",
491 | "ax.spines['top'].set_color('none')\n",
492 | "ax.xaxis.set_ticks_position('bottom')\n",
493 | "ax.spines['bottom'].set_position(('data',0))\n",
494 | "ax.yaxis.set_ticks_position('left')\n",
495 | "ax.spines['left'].set_position(('data',0)) #outward, axes, data\n",
496 | "\n",
497 | "for label in ax.get_xticklabels() + ax.get_yticklabels():\n",
498 | " label.set_fontsize(16)\n",
499 | " label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65))#probar valores de alpha y facecolor"
500 | ]
501 | },
502 | {
503 | "cell_type": "markdown",
504 | "metadata": {},
505 | "source": [
506 | "## Añadir Título"
507 | ]
508 | },
509 | {
510 | "cell_type": "code",
511 | "execution_count": null,
512 | "metadata": {},
513 | "outputs": [],
514 | "source": [
515 | "plt.figure(figsize=(10, 6), dpi=80)\n",
516 | "\n",
517 | "plt.plot(X, C, color=\"blue\", linewidth=2.5, linestyle=\"-\", label=\"coseno\")\n",
518 | "plt.plot(X, S, color=\"red\", linewidth=2.5, linestyle=\"-\", label=\"seno\")\n",
519 | "plt.legend(loc='upper left')\n",
520 | "\n",
521 | "plt.title(\"sin(x) y cos(x)\")\n",
522 | "t = 2 * np.pi / 3\n",
523 | "plt.plot([t, t], [0, np.cos(t)], color='blue', linewidth=2.5, linestyle=\"--\")\n",
524 | "plt.scatter([t, ], [np.cos(t), ], 50, color='blue')\n",
525 | "\n",
526 | "plt.annotate(r'$sin(\\frac{2\\pi}{3})=\\frac{\\sqrt{3}}{2}$',\n",
527 | " xy=(t, np.sin(t)), xycoords='data',\n",
528 | " xytext=(+10, +30), textcoords='offset points', fontsize=16,\n",
529 | " arrowprops=dict(arrowstyle=\"->\"))\n",
530 | "\n",
531 | "plt.plot([t, t],[0, np.sin(t)], color='red', linewidth=2.5, linestyle=\"--\")\n",
532 | "plt.scatter([t, ],[np.sin(t), ], 50, color='red') #probar eliminar\n",
533 | "\n",
534 | "plt.annotate(r'$cos(\\frac{2\\pi}{3})=-\\frac{1}{2}$',\n",
535 | " xy=(t, np.cos(t)), xycoords='data',\n",
536 | " xytext=(-90, -50), textcoords='offset points', fontsize=16,\n",
537 | " arrowprops=dict(arrowstyle=\"->\"))\n",
538 | "\n",
539 | "plt.xticks([-np.pi, -np.pi/2, 0, np.pi/2, np.pi],\n",
540 | " [r'$-\\pi$', r'$-\\pi/2$', r'$0$', r'$+\\pi/2$', r'$+\\pi$'])\n",
541 | "plt.yticks([-1, 0, +1],\n",
542 | " [r'$-1$', r'$0$', r'$+1$'])\n",
543 | "ax = plt.gca() # gca se ocupa para decir q nos referimos al grafico actual\n",
544 | "ax.spines['right'].set_color('none')\n",
545 | "ax.spines['top'].set_color('none')\n",
546 | "ax.xaxis.set_ticks_position('bottom')\n",
547 | "ax.spines['bottom'].set_position(('data',0))\n",
548 | "ax.yaxis.set_ticks_position('left')\n",
549 | "ax.spines['left'].set_position(('data',0)) #outward, axes, data\n",
550 | "\n",
551 | "for label in ax.get_xticklabels() + ax.get_yticklabels():\n",
552 | " label.set_fontsize(16)\n",
553 | " label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65))#probar valores de alpha y facecolor"
554 | ]
555 | },
556 | {
557 | "cell_type": "markdown",
558 | "metadata": {},
559 | "source": [
560 | "## Ejercicio\n",
561 | "\n",
562 | "Aplique todo lo visto anteriormente para representar las funciones *cosh(x)* y *sinh(x)* desde -2pi a 2pi, utilizando en el eje 'x' 256 valores distintos."
563 | ]
564 | },
565 | {
566 | "cell_type": "markdown",
567 | "metadata": {},
568 | "source": [
569 | "## Crear datos"
570 | ]
571 | },
572 | {
573 | "cell_type": "code",
574 | "execution_count": null,
575 | "metadata": {},
576 | "outputs": [],
577 | "source": []
578 | },
579 | {
580 | "cell_type": "markdown",
581 | "metadata": {},
582 | "source": [
583 | "## Graficar\n",
584 | "\n",
585 | "Debe lograr la siguiente figura\n",
586 | "\n",
587 | ""
588 | ]
589 | },
590 | {
591 | "cell_type": "code",
592 | "execution_count": null,
593 | "metadata": {},
594 | "outputs": [],
595 | "source": []
596 | },
597 | {
598 | "cell_type": "markdown",
599 | "metadata": {},
600 | "source": [
601 | "De datos a visualización "
602 | ]
603 | },
604 | {
605 | "cell_type": "markdown",
606 | "metadata": {},
607 | "source": [
608 | "## Datos\n",
609 | "\n",
610 | "Los datos muestran el número de ventas para ciertas compañías"
611 | ]
612 | },
613 | {
614 | "cell_type": "code",
615 | "execution_count": null,
616 | "metadata": {},
617 | "outputs": [],
618 | "source": [
619 | "import numpy as np\n",
620 | "import matplotlib.pyplot as plt\n",
621 | "from matplotlib.ticker import FuncFormatter\n",
622 | "\n",
623 | "data = {'Barton LLC': 109438.50,\n",
624 | " 'Frami, Hills and Schmidt': 103569.59,\n",
625 | " 'Fritsch, Russel and Anderson': 112214.71,\n",
626 | " 'Jerde-Hilpert': 112591.43,\n",
627 | " 'Keeling LLC': 100934.30,\n",
628 | " 'Koepp Ltd': 103660.54,\n",
629 | " 'Kulas Inc': 137351.96,\n",
630 | " 'Trantow-Barrows': 123381.38,\n",
631 | " 'White-Trantow': 135841.99,\n",
632 | " 'Will LLC': 104437.60}\n",
633 | "group_data = list(data.values())\n",
634 | "group_names = list(data.keys())\n",
635 | "group_mean = np.mean(group_data)"
636 | ]
637 | },
638 | {
639 | "cell_type": "markdown",
640 | "metadata": {},
641 | "source": [
642 | "¿Como visualizarían esta información? "
643 | ]
644 | },
645 | {
646 | "cell_type": "markdown",
647 | "metadata": {},
648 | "source": [
649 | "Esta data suele visualizarse utilizando *barplots* (gráfico de barras), donde cada barra corresponderá a un grupo. \n",
650 | "\n",
651 | "Para hacer esto, se puede crear una instancia de *figure* y *axes*. La *Figure* será nuestro 'canvas¿ y 'Axes' será una parte de nuestro canvas en donde haremos una visualización en particular"
652 | ]
653 | },
654 | {
655 | "cell_type": "code",
656 | "execution_count": null,
657 | "metadata": {},
658 | "outputs": [],
659 | "source": [
660 | "fig, ax = plt.subplots() #Figuras pueden tener multiples 'axes' dentro. "
661 | ]
662 | },
663 | {
664 | "cell_type": "markdown",
665 | "metadata": {},
666 | "source": [
667 | "Se ha creado una instancia de 'Axes', ahora podemos graficar en ella.\n",
668 | "\n",
669 | "'barh' crea un 'gráfico de barra horizontal'"
670 | ]
671 | },
672 | {
673 | "cell_type": "code",
674 | "execution_count": null,
675 | "metadata": {},
676 | "outputs": [],
677 | "source": [
678 | "fig, ax = plt.subplots()\n",
679 | "ax.barh(group_names, group_data) #cambiar barh por bar"
680 | ]
681 | },
682 | {
683 | "cell_type": "markdown",
684 | "metadata": {},
685 | "source": [
686 | "## Estilos\n",
687 | "\n",
688 | "Hay muchos estilos disponibles en Matplotlib con la idea de lograr una mejor visualización. \n"
689 | ]
690 | },
691 | {
692 | "cell_type": "code",
693 | "execution_count": null,
694 | "metadata": {},
695 | "outputs": [],
696 | "source": [
697 | "print(plt.style.available)\n"
698 | ]
699 | },
700 | {
701 | "cell_type": "markdown",
702 | "metadata": {},
703 | "source": [
704 | "Un estilo se puede activar de la siguiente forma"
705 | ]
706 | },
707 | {
708 | "cell_type": "code",
709 | "execution_count": null,
710 | "metadata": {},
711 | "outputs": [],
712 | "source": [
713 | "plt.style.use('fivethirtyeight') #seaborn-dark-palette\n",
714 | "fig, ax = plt.subplots()\n",
715 | "ax.barh(group_names, group_data)"
716 | ]
717 | },
718 | {
719 | "cell_type": "markdown",
720 | "metadata": {},
721 | "source": [
722 | "## Rotar ejes\n",
723 | "Si bien el gráfico va quedando bastante bien, es dificil distinguir cada una de los elementos del eje 'x'.\n",
724 | "Podemos rotar los ejes para permitir mayor claridad.\n",
725 | "\n",
726 | "Cuando se quiere cambiar la propiedad de muchos itemes a la vez, se puede utilizar la función 'setp'. Esta función tomará una lista (o muchas listas) de objetos de Matplotlib e intentará setear el estilo de cada uno de los elementos\n"
727 | ]
728 | },
729 | {
730 | "cell_type": "code",
731 | "execution_count": null,
732 | "metadata": {},
733 | "outputs": [],
734 | "source": [
735 | "fig, ax = plt.subplots()\n",
736 | "ax.barh(group_names, group_data)\n",
737 | "labels = ax.get_xticklabels() #Aqui tenemos acceso a las etiquetas de x\n",
738 | "plt.setp(labels, rotation=45, horizontalalignment='right');#se le paso la lista labels"
739 | ]
740 | },
741 | {
742 | "cell_type": "markdown",
743 | "metadata": {},
744 | "source": [
745 | "## Adjustar figura\n",
746 | "\n",
747 | "*tigh_layout* automaticamente ajusta parametros del subplot para que ocupe todo el espacio de la figura que está permitido. \n"
748 | ]
749 | },
750 | {
751 | "cell_type": "code",
752 | "execution_count": null,
753 | "metadata": {},
754 | "outputs": [],
755 | "source": [
756 | "\n",
757 | "fig, ax = plt.subplots()\n",
758 | "ax.barh(group_names, group_data)\n",
759 | "labels = ax.get_xticklabels()\n",
760 | "plt.setp(labels, rotation=45, horizontalalignment='right');\n",
761 | "plt.tight_layout()"
762 | ]
763 | },
764 | {
765 | "cell_type": "markdown",
766 | "metadata": {},
767 | "source": [
768 | "## Añadir etiquetas a la figura\n",
769 | "\n",
770 | "Añadamos límites, etiquetas y título"
771 | ]
772 | },
773 | {
774 | "cell_type": "code",
775 | "execution_count": null,
776 | "metadata": {},
777 | "outputs": [],
778 | "source": [
779 | "fig, ax = plt.subplots()\n",
780 | "ax.barh(group_names, group_data)\n",
781 | "labels = ax.get_xticklabels()\n",
782 | "plt.setp(labels, rotation=45, horizontalalignment='right')\n",
783 | "plt.tight_layout()\n",
784 | "ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',\n",
785 | " title='Company Revenue');"
786 | ]
787 | },
788 | {
789 | "cell_type": "markdown",
790 | "metadata": {},
791 | "source": [
792 | "## Cambiemos el tamaño de la figura"
793 | ]
794 | },
795 | {
796 | "cell_type": "code",
797 | "execution_count": null,
798 | "metadata": {},
799 | "outputs": [],
800 | "source": [
801 | "fig, ax = plt.subplots(figsize=(8, 4))\n",
802 | "ax.barh(group_names, group_data)\n",
803 | "labels = ax.get_xticklabels()\n",
804 | "plt.tight_layout()\n",
805 | "plt.setp(labels, rotation=45, horizontalalignment='right')\n",
806 | "ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',\n",
807 | " title='Company Revenue');"
808 | ]
809 | },
810 | {
811 | "cell_type": "markdown",
812 | "metadata": {},
813 | "source": [
814 | "## Establecer patrones en las etiquetas\n",
815 | "\n",
816 | "Se necesita la clase 'ticker.FuncFormatter'. \n",
817 | "\n",
818 | "Definamos una funcion que toma un entero como input y retorna un string como salida"
819 | ]
820 | },
821 | {
822 | "cell_type": "code",
823 | "execution_count": null,
824 | "metadata": {},
825 | "outputs": [],
826 | "source": [
827 | "def currency(x, pos): #valor y posicion\n",
828 | "\n",
829 | " if x >= 1e6:\n",
830 | " s = '${:1.1f}M'.format(x*1e-6)\n",
831 | " else:\n",
832 | " s = '${:1.0f}K'.format(x*1e-3)\n",
833 | " return s\n",
834 | "\n",
835 | "formatter = FuncFormatter(currency)"
836 | ]
837 | },
838 | {
839 | "cell_type": "markdown",
840 | "metadata": {},
841 | "source": [
842 | "Podemos aplicar esta función a las etiquetas de nuestra figura. Se debe utilizar el atributo 'xaxis'. Esto nos permite centrar la atención en un axis específico"
843 | ]
844 | },
845 | {
846 | "cell_type": "code",
847 | "execution_count": null,
848 | "metadata": {},
849 | "outputs": [],
850 | "source": [
851 | "fig, ax = plt.subplots(figsize=(6, 8))\n",
852 | "ax.barh(group_names, group_data)\n",
853 | "labels = ax.get_xticklabels()\n",
854 | "plt.setp(labels, rotation=45, horizontalalignment='right')\n",
855 | "ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',\n",
856 | " title='Company Revenue')\n",
857 | "plt.tight_layout()\n",
858 | "ax.xaxis.set_major_formatter(formatter) # se modifican etiquetas principales"
859 | ]
860 | },
861 | {
862 | "cell_type": "markdown",
863 | "metadata": {},
864 | "source": [
865 | "## Combinar con otras visualizaciones\n",
866 | "\n"
867 | ]
868 | },
869 | {
870 | "cell_type": "code",
871 | "execution_count": null,
872 | "metadata": {},
873 | "outputs": [],
874 | "source": [
875 | "fig, ax = plt.subplots(figsize=(6, 8))\n",
876 | "ax.barh(group_names, group_data)\n",
877 | "labels = ax.get_xticklabels()\n",
878 | "plt.setp(labels, rotation=45, horizontalalignment='right')\n",
879 | "ax.set(xlim=[-10000, 140000], xlabel='Total Revenue', ylabel='Company',\n",
880 | " title='Company Revenue')\n",
881 | "plt.tight_layout()\n",
882 | "ax.xaxis.set_major_formatter(formatter) # se modifican etiquetas principales\n",
883 | "#Añadir una linea vertical en el promedio de las compañías\n",
884 | "ax.axvline(group_mean, ls='--', color='r')\n",
885 | "\n",
886 | "# Agregar nuevas compañías\n",
887 | "for group in [3, 5, 8]:\n",
888 | " ax.text(145000, group, \"Nueva Empresa\", fontsize=10,\n",
889 | " verticalalignment=\"center\")"
890 | ]
891 | },
892 | {
893 | "cell_type": "markdown",
894 | "metadata": {},
895 | "source": [
896 | "## Guardar Imagen"
897 | ]
898 | },
899 | {
900 | "cell_type": "code",
901 | "execution_count": null,
902 | "metadata": {},
903 | "outputs": [],
904 | "source": [
905 | "print(fig.canvas.get_supported_filetypes())\n"
906 | ]
907 | },
908 | {
909 | "cell_type": "code",
910 | "execution_count": null,
911 | "metadata": {},
912 | "outputs": [],
913 | "source": [
914 | "\n",
915 | "#fig.savefig('sales.png', transparent=False, dpi=80, bbox_inches=\"tight\")"
916 | ]
917 | },
918 | {
919 | "cell_type": "markdown",
920 | "metadata": {},
921 | "source": [
922 | "## Ejercicio"
923 | ]
924 | },
925 | {
926 | "cell_type": "markdown",
927 | "metadata": {},
928 | "source": [
929 | " "
930 | ]
931 | },
932 | {
933 | "cell_type": "code",
934 | "execution_count": null,
935 | "metadata": {},
936 | "outputs": [],
937 | "source": [
938 | "peliculas ={\n",
939 | "'Avengers: Infinity War': ('27 de abril','Walt Disney Pictures',257698183),\n",
940 | "'Black Panther': ('16 de febrero','Walt Disney Pictures',202003951),\n",
941 | "'A Quiet Place':('6 de abril','Paramount',88203562),\n",
942 | "'Ready Player One':('29 de marzo','Warner Bros',41764050),\n",
943 | "'Cincuenta sombras liberadas':('9 de febrero','Universal Pictures',38560195),\n",
944 | "'Rampage':('13 de abril','Warner Bros',35753093),\n",
945 | "'A Wrinkle in Time':('9 de marzo','Walt Disney Pictures',33123609),\n",
946 | "'Insidious: The Last Key':('5 de enero','Universal Pictures',29581355),\n",
947 | "'Pacific Rim: Uprising':('23 de marzo','Universal Pictures',28116535),\n",
948 | "'Peter Rabbit':('9 de febrero','Sony / Columbia',25010928)\n",
949 | "}"
950 | ]
951 | },
952 | {
953 | "cell_type": "code",
954 | "execution_count": null,
955 | "metadata": {},
956 | "outputs": [],
957 | "source": []
958 | }
959 | ],
960 | "metadata": {
961 | "celltoolbar": "Slideshow",
962 | "kernelspec": {
963 | "display_name": "Python 2",
964 | "language": "python",
965 | "name": "python2"
966 | },
967 | "language_info": {
968 | "codemirror_mode": {
969 | "name": "ipython",
970 | "version": 2
971 | },
972 | "file_extension": ".py",
973 | "mimetype": "text/x-python",
974 | "name": "python",
975 | "nbconvert_exporter": "python",
976 | "pygments_lexer": "ipython2",
977 | "version": "2.7.14"
978 | }
979 | },
980 | "nbformat": 4,
981 | "nbformat_minor": 2
982 | }
983 |
--------------------------------------------------------------------------------
/Clase 5/Ticks.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 5/Ticks.png
--------------------------------------------------------------------------------
/Clase 5/axes.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 5/axes.png
--------------------------------------------------------------------------------
/Clase 5/ejercicio1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 5/ejercicio1.png
--------------------------------------------------------------------------------
/Clase 5/ejercicio11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 5/ejercicio11.png
--------------------------------------------------------------------------------
/Clase 5/ejercicio2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 5/ejercicio2.png
--------------------------------------------------------------------------------
/Clase 5/figureParameters.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 5/figureParameters.png
--------------------------------------------------------------------------------
/Clase 5/figureParts.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 5/figureParts.png
--------------------------------------------------------------------------------
/Clase 5/subplots.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 5/subplots.png
--------------------------------------------------------------------------------
/Clase 6/gqm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 6/gqm.png
--------------------------------------------------------------------------------
/Clase 6/mini_ejercicio1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 6/mini_ejercicio1.png
--------------------------------------------------------------------------------
/Clase 6/mini_ejercicio22.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 6/mini_ejercicio22.png
--------------------------------------------------------------------------------
/Clase 6/mini_ejercicio222.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 6/mini_ejercicio222.png
--------------------------------------------------------------------------------
/Clase 7/graf1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 7/graf1.png
--------------------------------------------------------------------------------
/Clase 7/graf2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 7/graf2.png
--------------------------------------------------------------------------------
/Clase 7/graf3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 7/graf3.png
--------------------------------------------------------------------------------
/Clase 7/graf4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 7/graf4.png
--------------------------------------------------------------------------------
/Clase 7/graf5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 7/graf5.png
--------------------------------------------------------------------------------
/Clase 7/prueba_plotly.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 7/prueba_plotly.png
--------------------------------------------------------------------------------
/Clase 7/torpedo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 7/torpedo.png
--------------------------------------------------------------------------------
/Clase 8/Clase 8.ipynb:
--------------------------------------------------------------------------------
1 | {
2 | "cells": [
3 | {
4 | "cell_type": "markdown",
5 | "metadata": {
6 | "slideshow": {
7 | "slide_type": "slide"
8 | }
9 | },
10 | "source": [
11 | "\n",
12 | " \n",
13 | "\n",
14 | " \n",
15 | "\n",
16 | "# Taller de Manejo y Visualización de Datos con Python\n",
17 | "ScatterText \n",
18 | "Felipe González P. \n",
19 | "felipe.gonzalezp.12@sansano.usm.cl \n",
20 | "\n",
21 | " \n",
22 | "Jueves Bloque 7-8 \n",
23 | "Campus San Joaquín\n",
24 | "\n",
25 | "\n"
26 | ]
27 | },
28 | {
29 | "cell_type": "markdown",
30 | "metadata": {
31 | "slideshow": {
32 | "slide_type": "slide"
33 | }
34 | },
35 | "source": [
36 | "# spaCy\n",
37 | "SpaCy es una biblioteca que tiene funciones para todas las tareas clave de NLP necesarias para preparar el texto para un análisis posterior, incluida la tokenización, el reconocimiento de entidades nombradas y los vectores de palabras, entre muchos otros. Su objetivo es proporcionar un proceso simplificado para que llegue al resultado final lo más rápido posible. No usaremos esto directamente, ya que es aprovechado automáticamente por la biblioteca Scattertext, pero dada su importancia en esta área, vale la pena mencionarlo."
38 | ]
39 | },
40 | {
41 | "cell_type": "markdown",
42 | "metadata": {
43 | "slideshow": {
44 | "slide_type": "slide"
45 | }
46 | },
47 | "source": [
48 | "# Scattertext\n",
49 | "\n",
50 | "Scattertext es un paquete de Python que permite comparar y contrastar cómo se usan las palabras de manera diferente en dos tipos de documentos, produciendo visualizaciones interactivas basadas en Javascript que pueden incorporarse fácilmente en los Jupyter Notebooks. Usando SpaCy y Empath, Scattertext también puede mostrar cómo los estados emocionales y las palabras se relacionan con un tema en particular.\n"
51 | ]
52 | },
53 | {
54 | "cell_type": "markdown",
55 | "metadata": {
56 | "slideshow": {
57 | "slide_type": "slide"
58 | }
59 | },
60 | "source": [
61 | " \n",
62 | "\n",
63 | "\n"
64 | ]
65 | },
66 | {
67 | "cell_type": "markdown",
68 | "metadata": {
69 | "slideshow": {
70 | "slide_type": "slide"
71 | }
72 | },
73 | "source": [
74 | " \n",
75 | ""
76 | ]
77 | },
78 | {
79 | "cell_type": "markdown",
80 | "metadata": {
81 | "slideshow": {
82 | "slide_type": "slide"
83 | }
84 | },
85 | "source": [
86 | "# Instalación \n",
87 | "```bash\n",
88 | "conda install -c conda-forge spacy\n",
89 | "conda install -c conda-forge scattertext\n",
90 | "python -m spacy download en\n",
91 | "```"
92 | ]
93 | },
94 | {
95 | "cell_type": "markdown",
96 | "metadata": {
97 | "slideshow": {
98 | "slide_type": "slide"
99 | }
100 | },
101 | "source": [
102 | "# Importar librerías "
103 | ]
104 | },
105 | {
106 | "cell_type": "code",
107 | "execution_count": 4,
108 | "metadata": {
109 | "slideshow": {
110 | "slide_type": "fragment"
111 | }
112 | },
113 | "outputs": [
114 | {
115 | "data": {
116 | "text/html": [
117 | ""
118 | ],
119 | "text/plain": [
120 | ""
121 | ]
122 | },
123 | "metadata": {},
124 | "output_type": "display_data"
125 | }
126 | ],
127 | "source": [
128 | "%matplotlib inline\n",
129 | "import pandas as pd\n",
130 | "import numpy as np\n",
131 | "import matplotlib.pyplot as plt\n",
132 | "import spacy\n",
133 | "from datetime import datetime\n",
134 | "import scattertext as st\n",
135 | "from IPython.display import IFrame\n",
136 | "from IPython.core.display import display, HTML\n",
137 | "display(HTML(\"\"))"
138 | ]
139 | },
140 | {
141 | "cell_type": "markdown",
142 | "metadata": {
143 | "slideshow": {
144 | "slide_type": "slide"
145 | }
146 | },
147 | "source": [
148 | "# Leer dataset\n",
149 | "Dataset obtenido desde GitHub "
150 | ]
151 | },
152 | {
153 | "cell_type": "code",
154 | "execution_count": 8,
155 | "metadata": {
156 | "slideshow": {
157 | "slide_type": "fragment"
158 | }
159 | },
160 | "outputs": [],
161 | "source": [
162 | "data = pd.read_csv(\"election_day_tweets_with_emojis_cleaned_VF.csv\")"
163 | ]
164 | },
165 | {
166 | "cell_type": "code",
167 | "execution_count": 9,
168 | "metadata": {
169 | "slideshow": {
170 | "slide_type": "fragment"
171 | }
172 | },
173 | "outputs": [
174 | {
175 | "data": {
176 | "text/html": [
177 | "\n",
178 | "\n",
191 | "
\n",
192 | " \n",
193 | " \n",
194 | " \n",
195 | " tweetindex \n",
196 | " text \n",
197 | " ts \n",
198 | " hour \n",
199 | " min \n",
200 | " lang \n",
201 | " source.r \n",
202 | " clinton \n",
203 | " trump \n",
204 | " election \n",
205 | " vote \n",
206 | " emoji.names \n",
207 | " url \n",
208 | " \n",
209 | " \n",
210 | " \n",
211 | " \n",
212 | " 0 \n",
213 | " 3 \n",
214 | " Is Election Day over yet \n",
215 | " 11/8/16 15:57 \n",
216 | " 15 \n",
217 | " 1557 \n",
218 | " en \n",
219 | " IOS \n",
220 | " 0 \n",
221 | " 0 \n",
222 | " 1 \n",
223 | " 0 \n",
224 | " expressionless face \n",
225 | " twitter.com/________kenzie/status/796094330494... \n",
226 | " \n",
227 | " \n",
228 | " 1 \n",
229 | " 5 \n",
230 | " Do people not vote for the Green Party because... \n",
231 | " 11/8/16 15:22 \n",
232 | " 15 \n",
233 | " 1522 \n",
234 | " en \n",
235 | " WEB \n",
236 | " 0 \n",
237 | " 0 \n",
238 | " 1 \n",
239 | " 1 \n",
240 | " thinking face \n",
241 | " twitter.com/________owl/status/796085601938313217 \n",
242 | " \n",
243 | " \n",
244 | " 2 \n",
245 | " 13 \n",
246 | " anyways, I voted \n",
247 | " 11/8/16 18:09 \n",
248 | " 18 \n",
249 | " 1809 \n",
250 | " en \n",
251 | " IOS \n",
252 | " 0 \n",
253 | " 0 \n",
254 | " 0 \n",
255 | " 1 \n",
256 | " hugging face \n",
257 | " twitter.com/_______kml/status/796127605422522373 \n",
258 | " \n",
259 | " \n",
260 | " 3 \n",
261 | " 15 \n",
262 | " Mfs Steady Talking Bout The Election How Many ... \n",
263 | " 11/8/16 16:23 \n",
264 | " 16 \n",
265 | " 1623 \n",
266 | " en \n",
267 | " IOS \n",
268 | " 0 \n",
269 | " 0 \n",
270 | " 1 \n",
271 | " 1 \n",
272 | " face with tears of joy, sleeping face \n",
273 | " twitter.com/_______KrewNate/status/79610077736... \n",
274 | " \n",
275 | " \n",
276 | " 4 \n",
277 | " 18 \n",
278 | " good thing i can't vote \n",
279 | " 11/8/16 11:12 \n",
280 | " 11 \n",
281 | " 1112 \n",
282 | " en \n",
283 | " IOS \n",
284 | " 0 \n",
285 | " 0 \n",
286 | " 0 \n",
287 | " 1 \n",
288 | " hugging face, Puerto Rico \n",
289 | " twitter.com/_______richard/status/796022544570... \n",
290 | " \n",
291 | " \n",
292 | " 5 \n",
293 | " 21 \n",
294 | " 1 vote won't change anything \n",
295 | " 11/8/16 23:19 \n",
296 | " 23 \n",
297 | " 2319 \n",
298 | " en \n",
299 | " IOS \n",
300 | " 0 \n",
301 | " 0 \n",
302 | " 0 \n",
303 | " 1 \n",
304 | " face with rolling eyes \n",
305 | " twitter.com/______aMoya/status/796205457979428864 \n",
306 | " \n",
307 | " \n",
308 | " 6 \n",
309 | " 22 \n",
310 | " make sure yall get out and VOTE today!! \n",
311 | " 11/8/16 6:31 \n",
312 | " 6 \n",
313 | " 631 \n",
314 | " en \n",
315 | " OTHER \n",
316 | " 0 \n",
317 | " 0 \n",
318 | " 0 \n",
319 | " 1 \n",
320 | " double exclamation mark \n",
321 | " twitter.com/______Ashlee/status/79595176059457... \n",
322 | " \n",
323 | " \n",
324 | " 7 \n",
325 | " 38 \n",
326 | " This Election Really Show How Fucking Smart Th... \n",
327 | " 11/8/16 22:15 \n",
328 | " 22 \n",
329 | " 2215 \n",
330 | " en \n",
331 | " IOS \n",
332 | " 0 \n",
333 | " 0 \n",
334 | " 1 \n",
335 | " 0 \n",
336 | " expressionless face \n",
337 | " twitter.com/______raeeeeee/status/796189489907... \n",
338 | " \n",
339 | " \n",
340 | " 8 \n",
341 | " 49 \n",
342 | " This is actually shocking. But then again, hon... \n",
343 | " 11/8/16 22:32 \n",
344 | " 22 \n",
345 | " 2232 \n",
346 | " en \n",
347 | " IOS \n",
348 | " 0 \n",
349 | " 0 \n",
350 | " 0 \n",
351 | " 1 \n",
352 | " face with rolling eyes \n",
353 | " twitter.com/_____armani/status/796193747176398849 \n",
354 | " \n",
355 | " \n",
356 | " 9 \n",
357 | " 53 \n",
358 | " My snapchat story/rant about this election is ... \n",
359 | " 11/8/16 13:32 \n",
360 | " 13 \n",
361 | " 1332 \n",
362 | " en \n",
363 | " IOS \n",
364 | " 0 \n",
365 | " 0 \n",
366 | " 1 \n",
367 | " 0 \n",
368 | " face with tears of joy, United States \n",
369 | " twitter.com/_____bat/status/796057835461283840 \n",
370 | " \n",
371 | " \n",
372 | "
\n",
373 | "
"
374 | ],
375 | "text/plain": [
376 | " tweetindex text \\\n",
377 | "0 3 Is Election Day over yet \n",
378 | "1 5 Do people not vote for the Green Party because... \n",
379 | "2 13 anyways, I voted \n",
380 | "3 15 Mfs Steady Talking Bout The Election How Many ... \n",
381 | "4 18 good thing i can't vote \n",
382 | "5 21 1 vote won't change anything \n",
383 | "6 22 make sure yall get out and VOTE today!! \n",
384 | "7 38 This Election Really Show How Fucking Smart Th... \n",
385 | "8 49 This is actually shocking. But then again, hon... \n",
386 | "9 53 My snapchat story/rant about this election is ... \n",
387 | "\n",
388 | " ts hour min lang source.r clinton trump election vote \\\n",
389 | "0 11/8/16 15:57 15 1557 en IOS 0 0 1 0 \n",
390 | "1 11/8/16 15:22 15 1522 en WEB 0 0 1 1 \n",
391 | "2 11/8/16 18:09 18 1809 en IOS 0 0 0 1 \n",
392 | "3 11/8/16 16:23 16 1623 en IOS 0 0 1 1 \n",
393 | "4 11/8/16 11:12 11 1112 en IOS 0 0 0 1 \n",
394 | "5 11/8/16 23:19 23 2319 en IOS 0 0 0 1 \n",
395 | "6 11/8/16 6:31 6 631 en OTHER 0 0 0 1 \n",
396 | "7 11/8/16 22:15 22 2215 en IOS 0 0 1 0 \n",
397 | "8 11/8/16 22:32 22 2232 en IOS 0 0 0 1 \n",
398 | "9 11/8/16 13:32 13 1332 en IOS 0 0 1 0 \n",
399 | "\n",
400 | " emoji.names \\\n",
401 | "0 expressionless face \n",
402 | "1 thinking face \n",
403 | "2 hugging face \n",
404 | "3 face with tears of joy, sleeping face \n",
405 | "4 hugging face, Puerto Rico \n",
406 | "5 face with rolling eyes \n",
407 | "6 double exclamation mark \n",
408 | "7 expressionless face \n",
409 | "8 face with rolling eyes \n",
410 | "9 face with tears of joy, United States \n",
411 | "\n",
412 | " url \n",
413 | "0 twitter.com/________kenzie/status/796094330494... \n",
414 | "1 twitter.com/________owl/status/796085601938313217 \n",
415 | "2 twitter.com/_______kml/status/796127605422522373 \n",
416 | "3 twitter.com/_______KrewNate/status/79610077736... \n",
417 | "4 twitter.com/_______richard/status/796022544570... \n",
418 | "5 twitter.com/______aMoya/status/796205457979428864 \n",
419 | "6 twitter.com/______Ashlee/status/79595176059457... \n",
420 | "7 twitter.com/______raeeeeee/status/796189489907... \n",
421 | "8 twitter.com/_____armani/status/796193747176398849 \n",
422 | "9 twitter.com/_____bat/status/796057835461283840 "
423 | ]
424 | },
425 | "execution_count": 9,
426 | "metadata": {},
427 | "output_type": "execute_result"
428 | }
429 | ],
430 | "source": [
431 | "data.head(10)"
432 | ]
433 | },
434 | {
435 | "cell_type": "markdown",
436 | "metadata": {
437 | "slideshow": {
438 | "slide_type": "slide"
439 | }
440 | },
441 | "source": [
442 | "# Analizar tweets por hora "
443 | ]
444 | },
445 | {
446 | "cell_type": "code",
447 | "execution_count": 49,
448 | "metadata": {
449 | "slideshow": {
450 | "slide_type": "fragment"
451 | }
452 | },
453 | "outputs": [],
454 | "source": [
455 | "import time\n",
456 | "def transform_datetime(x):\n",
457 | " try:\n",
458 | " return time.strftime('%y-%m-%d %H:00', time.strptime(x,'%m/%d/%y %H:%M'))\n",
459 | " except:\n",
460 | " pass\n",
461 | "data['created_at'] = data.ts.apply(transform_datetime)\n"
462 | ]
463 | },
464 | {
465 | "cell_type": "code",
466 | "execution_count": 50,
467 | "metadata": {
468 | "slideshow": {
469 | "slide_type": "fragment"
470 | }
471 | },
472 | "outputs": [
473 | {
474 | "data": {
475 | "text/html": [
476 | "\n",
477 | "\n",
490 | "
\n",
491 | " \n",
492 | " \n",
493 | " \n",
494 | " tweetindex \n",
495 | " text \n",
496 | " ts \n",
497 | " hour \n",
498 | " min \n",
499 | " lang \n",
500 | " source.r \n",
501 | " clinton \n",
502 | " trump \n",
503 | " election \n",
504 | " vote \n",
505 | " emoji.names \n",
506 | " url \n",
507 | " created_at \n",
508 | " \n",
509 | " \n",
510 | " \n",
511 | " \n",
512 | " 0 \n",
513 | " 3 \n",
514 | " Is Election Day over yet \n",
515 | " 11/8/16 15:57 \n",
516 | " 15 \n",
517 | " 1557 \n",
518 | " en \n",
519 | " IOS \n",
520 | " 0 \n",
521 | " 0 \n",
522 | " 1 \n",
523 | " 0 \n",
524 | " expressionless face \n",
525 | " twitter.com/________kenzie/status/796094330494... \n",
526 | " 16-11-08 15:00 \n",
527 | " \n",
528 | " \n",
529 | " 1 \n",
530 | " 5 \n",
531 | " Do people not vote for the Green Party because... \n",
532 | " 11/8/16 15:22 \n",
533 | " 15 \n",
534 | " 1522 \n",
535 | " en \n",
536 | " WEB \n",
537 | " 0 \n",
538 | " 0 \n",
539 | " 1 \n",
540 | " 1 \n",
541 | " thinking face \n",
542 | " twitter.com/________owl/status/796085601938313217 \n",
543 | " 16-11-08 15:00 \n",
544 | " \n",
545 | " \n",
546 | " 2 \n",
547 | " 13 \n",
548 | " anyways, I voted \n",
549 | " 11/8/16 18:09 \n",
550 | " 18 \n",
551 | " 1809 \n",
552 | " en \n",
553 | " IOS \n",
554 | " 0 \n",
555 | " 0 \n",
556 | " 0 \n",
557 | " 1 \n",
558 | " hugging face \n",
559 | " twitter.com/_______kml/status/796127605422522373 \n",
560 | " 16-11-08 18:00 \n",
561 | " \n",
562 | " \n",
563 | " 3 \n",
564 | " 15 \n",
565 | " Mfs Steady Talking Bout The Election How Many ... \n",
566 | " 11/8/16 16:23 \n",
567 | " 16 \n",
568 | " 1623 \n",
569 | " en \n",
570 | " IOS \n",
571 | " 0 \n",
572 | " 0 \n",
573 | " 1 \n",
574 | " 1 \n",
575 | " face with tears of joy, sleeping face \n",
576 | " twitter.com/_______KrewNate/status/79610077736... \n",
577 | " 16-11-08 16:00 \n",
578 | " \n",
579 | " \n",
580 | " 4 \n",
581 | " 18 \n",
582 | " good thing i can't vote \n",
583 | " 11/8/16 11:12 \n",
584 | " 11 \n",
585 | " 1112 \n",
586 | " en \n",
587 | " IOS \n",
588 | " 0 \n",
589 | " 0 \n",
590 | " 0 \n",
591 | " 1 \n",
592 | " hugging face, Puerto Rico \n",
593 | " twitter.com/_______richard/status/796022544570... \n",
594 | " 16-11-08 11:00 \n",
595 | " \n",
596 | " \n",
597 | "
\n",
598 | "
"
599 | ],
600 | "text/plain": [
601 | " tweetindex text \\\n",
602 | "0 3 Is Election Day over yet \n",
603 | "1 5 Do people not vote for the Green Party because... \n",
604 | "2 13 anyways, I voted \n",
605 | "3 15 Mfs Steady Talking Bout The Election How Many ... \n",
606 | "4 18 good thing i can't vote \n",
607 | "\n",
608 | " ts hour min lang source.r clinton trump election vote \\\n",
609 | "0 11/8/16 15:57 15 1557 en IOS 0 0 1 0 \n",
610 | "1 11/8/16 15:22 15 1522 en WEB 0 0 1 1 \n",
611 | "2 11/8/16 18:09 18 1809 en IOS 0 0 0 1 \n",
612 | "3 11/8/16 16:23 16 1623 en IOS 0 0 1 1 \n",
613 | "4 11/8/16 11:12 11 1112 en IOS 0 0 0 1 \n",
614 | "\n",
615 | " emoji.names \\\n",
616 | "0 expressionless face \n",
617 | "1 thinking face \n",
618 | "2 hugging face \n",
619 | "3 face with tears of joy, sleeping face \n",
620 | "4 hugging face, Puerto Rico \n",
621 | "\n",
622 | " url created_at \n",
623 | "0 twitter.com/________kenzie/status/796094330494... 16-11-08 15:00 \n",
624 | "1 twitter.com/________owl/status/796085601938313217 16-11-08 15:00 \n",
625 | "2 twitter.com/_______kml/status/796127605422522373 16-11-08 18:00 \n",
626 | "3 twitter.com/_______KrewNate/status/79610077736... 16-11-08 16:00 \n",
627 | "4 twitter.com/_______richard/status/796022544570... 16-11-08 11:00 "
628 | ]
629 | },
630 | "execution_count": 50,
631 | "metadata": {},
632 | "output_type": "execute_result"
633 | }
634 | ],
635 | "source": [
636 | "data.head()"
637 | ]
638 | },
639 | {
640 | "cell_type": "markdown",
641 | "metadata": {
642 | "slideshow": {
643 | "slide_type": "slide"
644 | }
645 | },
646 | "source": [
647 | "# Cantidad del dataset "
648 | ]
649 | },
650 | {
651 | "cell_type": "code",
652 | "execution_count": 51,
653 | "metadata": {
654 | "slideshow": {
655 | "slide_type": "fragment"
656 | }
657 | },
658 | "outputs": [
659 | {
660 | "data": {
661 | "text/plain": [
662 | "175655"
663 | ]
664 | },
665 | "execution_count": 51,
666 | "metadata": {},
667 | "output_type": "execute_result"
668 | }
669 | ],
670 | "source": [
671 | "len(data)"
672 | ]
673 | },
674 | {
675 | "cell_type": "markdown",
676 | "metadata": {
677 | "slideshow": {
678 | "slide_type": "fragment"
679 | }
680 | },
681 | "source": [
682 | "# Categorizemos los tweets"
683 | ]
684 | },
685 | {
686 | "cell_type": "code",
687 | "execution_count": 52,
688 | "metadata": {
689 | "slideshow": {
690 | "slide_type": "fragment"
691 | }
692 | },
693 | "outputs": [],
694 | "source": [
695 | "data_clinton = data[data['clinton']==1]\n",
696 | "data_trump = data[data['trump']==1]"
697 | ]
698 | },
699 | {
700 | "cell_type": "markdown",
701 | "metadata": {
702 | "slideshow": {
703 | "slide_type": "slide"
704 | }
705 | },
706 | "source": [
707 | "¿Cuántos escriben tweets sobre Clinton? ¿Cuántos sobre Trump?"
708 | ]
709 | },
710 | {
711 | "cell_type": "markdown",
712 | "metadata": {
713 | "slideshow": {
714 | "slide_type": "slide"
715 | }
716 | },
717 | "source": [
718 | "# Veamos los tweets en el tiempo"
719 | ]
720 | },
721 | {
722 | "cell_type": "code",
723 | "execution_count": 53,
724 | "metadata": {
725 | "slideshow": {
726 | "slide_type": "fragment"
727 | }
728 | },
729 | "outputs": [],
730 | "source": [
731 | "tweets_over_time_clinton = data_clinton.groupby('created_at').size()\n",
732 | "tweets_over_time_trump = data_trump.groupby('created_at').size()\n"
733 | ]
734 | },
735 | {
736 | "cell_type": "code",
737 | "execution_count": 54,
738 | "metadata": {
739 | "slideshow": {
740 | "slide_type": "fragment"
741 | }
742 | },
743 | "outputs": [
744 | {
745 | "data": {
746 | "text/plain": [
747 | "created_at\n",
748 | "16-11-08 01:00 421\n",
749 | "16-11-08 02:00 758\n",
750 | "16-11-08 03:00 743\n",
751 | "16-11-08 04:00 545\n",
752 | "16-11-08 05:00 631\n",
753 | "16-11-08 06:00 861\n",
754 | "16-11-08 07:00 1349\n",
755 | "16-11-08 08:00 1743\n",
756 | "16-11-08 09:00 1827\n",
757 | "16-11-08 10:00 1799\n",
758 | "16-11-08 11:00 1736\n",
759 | "16-11-08 12:00 1608\n",
760 | "16-11-08 13:00 1472\n",
761 | "16-11-08 14:00 1438\n",
762 | "16-11-08 15:00 1467\n",
763 | "16-11-08 16:00 1064\n",
764 | "16-11-08 17:00 1079\n",
765 | "16-11-08 18:00 1121\n",
766 | "16-11-08 19:00 1311\n",
767 | "16-11-08 20:00 1500\n",
768 | "16-11-08 21:00 1166\n",
769 | "16-11-08 22:00 1021\n",
770 | "16-11-08 23:00 898\n",
771 | "16-11-09 00:00 685\n",
772 | "16-11-09 01:00 735\n",
773 | "16-11-09 02:00 1016\n",
774 | "16-11-09 03:00 466\n",
775 | "dtype: int64"
776 | ]
777 | },
778 | "execution_count": 54,
779 | "metadata": {},
780 | "output_type": "execute_result"
781 | }
782 | ],
783 | "source": [
784 | "tweets_over_time_clinton"
785 | ]
786 | },
787 | {
788 | "cell_type": "markdown",
789 | "metadata": {
790 | "slideshow": {
791 | "slide_type": "slide"
792 | }
793 | },
794 | "source": [
795 | "# Grafiquemos "
796 | ]
797 | },
798 | {
799 | "cell_type": "code",
800 | "execution_count": 58,
801 | "metadata": {},
802 | "outputs": [
803 | {
804 | "data": {
805 | "image/png": "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wHHHHccZZ5zB8OHDeeSRRxgxYgQvvfQSAAsWLGDChAlMnjyZU045haFDh6buCYuIiIiISFZQjWLIPvjgA4YOHUrLli0BaN68eZnbn3TSSQD06dOHOXPmxN3mk08+4dRTTwVg2LBhTJgwYeu6E088kZycHLp27cqiRYtS8AxERERERCTbqEYxUF7NX7o45yo00midOnUAyM3NZfPmzUk9Jnr/kcdHyhYRERERyVoT72evL1+GgQPDjiTjqEYxZAMHDmT06NEsXboUgGXLllV4H40aNWL16tVb/+/fvz+jRo0C4Omnn+aggw5KTbAiIiIiIplk2rPssvhjWLci7EgyjhLFkHXr1o1rrrmGAQMGsM8++3DZZZdVeB/HHXccL7744tbBbO666y4effRRevbsyZNPPsmdd96ZhshFRERERKqxDWtg4Rf+73mTw40lA6npaTUwfPhwhg8fHnfdY489tvXv6D6JhYWFjBs3DoA999yT6dOnb/e4sWPHlrkvgDVr1lQqXhERERGRam/eZHBbtv29x5Bw48kwqlEUEREREZHsU/wpAOvrtIKSz0IOJvOoRlFERERERLJP8URo1Y3lufm0LZkEzkEFBpGs6VSjKCIiIiIi2aW0FIo/g/b7sapxF1i3DJZ9H3ZUGUWJooiIiIiIZJfFs2DDSmi3P6sa7+mXlUwKN6YMo0RRRERERESyy9yJ/r79fvzcoB3Ubqh+ihWkRFFERERERLJLcRE02AWadQTLhV17wzzVKFaEEsWQrVixgpEjR4YdhoiIiIhI9pg7Edrvt23wmoJCP6fipnXhxpVBlCiGbOXKlXETxS1btoQQjYiIiIhIhlu9EFb8CO3227asoC+UboYF0xM/TrajRDFk1113Hd999x29evWib9++DBo0iFNPPZUePXowZ84cunfvvnXb2267jeuvvx6AgQMHcumll3LIIYfQrVs3PvvsM0466SQ6d+7Mn//8ZwDmzJlD165dGT58OD179mTo0KGsXbs2jKcpIiIiIlI1Iv0T2+2/bVl+ob9XP8WkaR7FiDev8tXRqdSmBxx1a5mb3HDDDcyePZupU6cybtw4jjnmGGbMmEHHjh2ZM2dOmY+tXbs2H374IXfeeScnnHACkydPpnnz5uy+++5ceumlAMyePZuHH36YAw88kLPPPpuRI0dyxRVXpOoZioiIiIhUL8Wf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\n",
806 | "text/plain": [
807 | ""
808 | ]
809 | },
810 | "metadata": {},
811 | "output_type": "display_data"
812 | }
813 | ],
814 | "source": [
815 | "plt.figure(figsize=(15,6))\n",
816 | "plt.title(\"Tweets en el tiempo en el día de elecciones según candidato\", fontsize=20)\n",
817 | "\n",
818 | "plt.plot(tweets_over_time_clinton, label=\"clinton\")\n",
819 | "plt.plot(tweets_over_time_trump, label=\"trump\")\n",
820 | "\n",
821 | "\n",
822 | "plt.ylabel('Número de tweets', fontsize=16)\n",
823 | "plt.xlabel(\"Año-Mes-Día Hora \", fontsize=16)\n",
824 | "plt.legend()\n",
825 | "plt.xticks(rotation=70)\n",
826 | "plt.grid(True)\n",
827 | "plt.show()"
828 | ]
829 | },
830 | {
831 | "cell_type": "markdown",
832 | "metadata": {
833 | "slideshow": {
834 | "slide_type": "slide"
835 | }
836 | },
837 | "source": [
838 | "
Usemos ScatterText "
839 | ]
840 | },
841 | {
842 | "cell_type": "markdown",
843 | "metadata": {
844 | "slideshow": {
845 | "slide_type": "slide"
846 | }
847 | },
848 | "source": [
849 | "## Cargaremos un modelo, este contiene vocabulario, entidades y sintáxis propia del idioma. No lo usaremos directamente"
850 | ]
851 | },
852 | {
853 | "cell_type": "code",
854 | "execution_count": 59,
855 | "metadata": {
856 | "slideshow": {
857 | "slide_type": "fragment"
858 | }
859 | },
860 | "outputs": [],
861 | "source": [
862 | "nlp = spacy.load('en')"
863 | ]
864 | },
865 | {
866 | "cell_type": "markdown",
867 | "metadata": {
868 | "slideshow": {
869 | "slide_type": "slide"
870 | }
871 | },
872 | "source": [
873 | "## Crearemos una nueva columna en los dos dataframe creados"
874 | ]
875 | },
876 | {
877 | "cell_type": "code",
878 | "execution_count": 61,
879 | "metadata": {
880 | "slideshow": {
881 | "slide_type": "fragment"
882 | }
883 | },
884 | "outputs": [],
885 | "source": [
886 | "data_clinton['category'] = 'clinton'\n",
887 | "data_trump['category'] = 'trump'\n"
888 | ]
889 | },
890 | {
891 | "cell_type": "markdown",
892 | "metadata": {
893 | "slideshow": {
894 | "slide_type": "slide"
895 | }
896 | },
897 | "source": [
898 | "## Uniremos todo"
899 | ]
900 | },
901 | {
902 | "cell_type": "code",
903 | "execution_count": 62,
904 | "metadata": {
905 | "slideshow": {
906 | "slide_type": "fragment"
907 | }
908 | },
909 | "outputs": [],
910 | "source": [
911 | "data_night_election = pd.concat([data_clinton[['category','url','text']], data_trump[['category','url','text']]])\n"
912 | ]
913 | },
914 | {
915 | "cell_type": "markdown",
916 | "metadata": {
917 | "slideshow": {
918 | "slide_type": "slide"
919 | }
920 | },
921 | "source": [
922 | "# Alerta\n",
923 | "\n",
924 | "Si correrá los siguientes códigos, debe tener cuenta que tomará tiempo obtener el resultado. Es recomendable hacer un sample. "
925 | ]
926 | },
927 | {
928 | "cell_type": "markdown",
929 | "metadata": {
930 | "slideshow": {
931 | "slide_type": "slide"
932 | }
933 | },
934 | "source": [
935 | "# Corpus \n",
936 | "\n",
937 | "Un corpus lingüístico es un conjunto amplio y estructurado de ejemplos reales de uso de la lengua. Estos ejemplos pueden ser textos, o muestras orales\n"
938 | ]
939 | },
940 | {
941 | "cell_type": "markdown",
942 | "metadata": {
943 | "slideshow": {
944 | "slide_type": "slide"
945 | }
946 | },
947 | "source": [
948 | "# Crearemos un corpus a partir de un dataframe\n"
949 | ]
950 | },
951 | {
952 | "cell_type": "code",
953 | "execution_count": 35,
954 | "metadata": {
955 | "slideshow": {
956 | "slide_type": "fragment"
957 | }
958 | },
959 | "outputs": [
960 | {
961 | "name": "stdout",
962 | "output_type": "stream",
963 | "text": [
964 | "Duration: 0:17:39.146936\n"
965 | ]
966 | }
967 | ],
968 | "source": [
969 | "start_time = datetime.now() \n",
970 | "corpus_data_night_election = st.CorpusFromPandas(data_night_election,category_col='category', text_col='text', nlp=nlp).build() \n",
971 | "end_time = datetime.now()\n",
972 | "print('Duration: {}'.format(end_time - start_time))\n"
973 | ]
974 | },
975 | {
976 | "cell_type": "markdown",
977 | "metadata": {
978 | "slideshow": {
979 | "slide_type": "slide"
980 | }
981 | },
982 | "source": [
983 | "# Veamos términos frecuentes en la noche de elecciones"
984 | ]
985 | },
986 | {
987 | "cell_type": "code",
988 | "execution_count": 40,
989 | "metadata": {
990 | "slideshow": {
991 | "slide_type": "fragment"
992 | }
993 | },
994 | "outputs": [
995 | {
996 | "data": {
997 | "text/plain": [
998 | "12907510"
999 | ]
1000 | },
1001 | "execution_count": 40,
1002 | "metadata": {},
1003 | "output_type": "execute_result"
1004 | }
1005 | ],
1006 | "source": [
1007 | "mininum = 500\n",
1008 | "html_group_4_english = st.produce_scattertext_explorer(corpus_data_night_election, category='clinton', \n",
1009 | " category_name='Clinton', \n",
1010 | " not_category_name='Trump',\n",
1011 | " minimum_term_frequency = mininum,\n",
1012 | " width_in_pixels=1000, \n",
1013 | " metadata=data_night_election['url'])\n",
1014 | "open(\"Night_elections.html\", 'wb').write(html_group_4_english.encode('utf-8'))\n"
1015 | ]
1016 | },
1017 | {
1018 | "cell_type": "markdown",
1019 | "metadata": {
1020 | "slideshow": {
1021 | "slide_type": "slide"
1022 | }
1023 | },
1024 | "source": [
1025 | "# Hagamos Topic Modeling"
1026 | ]
1027 | },
1028 | {
1029 | "cell_type": "code",
1030 | "execution_count": 42,
1031 | "metadata": {
1032 | "slideshow": {
1033 | "slide_type": "fragment"
1034 | }
1035 | },
1036 | "outputs": [],
1037 | "source": [
1038 | "feat_builder = st.FeatsFromOnlyEmpath()\n",
1039 | "empath_corpush = st.CorpusFromParsedDocuments(data_night_election,\n",
1040 | " category_col='category',\n",
1041 | " feats_from_spacy_doc=feat_builder,\n",
1042 | " parsed_col='text').build()\n"
1043 | ]
1044 | },
1045 | {
1046 | "cell_type": "code",
1047 | "execution_count": 46,
1048 | "metadata": {
1049 | "slideshow": {
1050 | "slide_type": "fragment"
1051 | }
1052 | },
1053 | "outputs": [
1054 | {
1055 | "data": {
1056 | "text/plain": [
1057 | "16687660"
1058 | ]
1059 | },
1060 | "execution_count": 46,
1061 | "metadata": {},
1062 | "output_type": "execute_result"
1063 | }
1064 | ],
1065 | "source": [
1066 | "html = st.produce_scattertext_explorer(empath_corpush,\n",
1067 | "... category='clinton',\n",
1068 | "... category_name='Clinton',\n",
1069 | "... not_category_name='Trump',\n",
1070 | "... width_in_pixels=1000,\n",
1071 | "... metadata=data_night_election['url'],\n",
1072 | "... use_non_text_features=True,\n",
1073 | "... use_full_doc=True,\n",
1074 | "... topic_model_term_lists=feat_builder.get_top_model_term_lists())\n",
1075 | "open(\"Topic-Night-Elections.html\", 'wb').write(html.encode('utf-8'))"
1076 | ]
1077 | }
1078 | ],
1079 | "metadata": {
1080 | "celltoolbar": "Slideshow",
1081 | "kernelspec": {
1082 | "display_name": "Python 3",
1083 | "language": "python",
1084 | "name": "python3"
1085 | },
1086 | "language_info": {
1087 | "codemirror_mode": {
1088 | "name": "ipython",
1089 | "version": 3
1090 | },
1091 | "file_extension": ".py",
1092 | "mimetype": "text/x-python",
1093 | "name": "python",
1094 | "nbconvert_exporter": "python",
1095 | "pygments_lexer": "ipython3",
1096 | "version": "3.6.4"
1097 | }
1098 | },
1099 | "nbformat": 4,
1100 | "nbformat_minor": 2
1101 | }
1102 |
--------------------------------------------------------------------------------
/Clase 8/data-society-major-speeches-by-donald-trump.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 8/data-society-major-speeches-by-donald-trump.zip
--------------------------------------------------------------------------------
/Clase 8/data-society-twitters-about-us-airline.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gonzalezf/Data-Analysis-and-Visualization-with-Python/475bb944a004bc3e5b2f94d7484b76fefe39a3ca/Clase 8/data-society-twitters-about-us-airline.zip
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Data Analysis and Visualization with Python
2 | #### Taller de manejo y visualización de datos con Python
3 |
4 | **Descripción**: En este taller los estudiantes desarrollaran habilidades de análisis de datos y visualización de información. Se ulizará Python con el framework Anaconda y las librerías Pandas y Matplotlib
5 |
6 | **Requisitos de entrada**: Conocimientos básicos de programación (IWI-131)
7 |
8 | **Competencias Específicas del Perfil de Egreso a las que contribuye**:
9 |
10 | 1. Modelos y métodos: Diseña y aplica métodos estadíscos para el análisis y la interpretación
11 | de datos y el diseño de experimentos computacionales.
12 | 2. Modelos y métodos: Aprende a enfrentar y proponer soluciones usando estrategias
13 | algorítmicas en problemas complejos
14 |
15 |
16 | **Competencias Transversales del Perfil de Egreso a las que contribuye**:
17 | 1. Comunicar información oral y escrita de manera eficaz al interior de las organizaciones en las
18 | que se desempeña, como con endades del entorno.
19 | 2. Actuar con autonomía, flexibilidad, iniciava, y pensamiento críco al enfrentar problemácas
20 | de la profesión .
21 |
22 |
23 | **Objetivos** (Resultados del aprendizaje): Al aprobar la asignatura, el estudiante será capaz de:
24 |
25 | 1. Extraer conjuntos de datos (_datasets_) desde laweb
26 | 2. Aplicar técnicas de limpieza dedatos
27 | 3. Aplicar distintas técnicas de visualización deinformación
28 | 4. Conocer aplicaciones de análisis y visualización de información en laindustria
29 | 5. Presentar de manera oral y escrita trabajo de análisis sobre un determinadodataset.
30 |
31 | **Metodología de enseñanza y de aprendizaje**:
32 | 1. Clases exposivas, material de apoyo teórico disponible para leer después de clases.
33 | 2. Se presentan ejemplos en la industria para mostrar como el análisis de datos y visualización de
34 | información logran resolver problemas actuales.
35 | 3. En el informe preliminar el estudiante debe dar a conocer el dataset que ulizará en el trabajo
36 | final junto con las preguntas que intentará responder.
37 | 4. En el trabajo final el alumno debe extraer información valiosa desde un dataset de su elección,
38 | manejando los datos con Pandas y visualizando los resultados con Matplotlib. Los resultados
39 | son reportados en un informe escrito y en una presentación.
40 |
41 |
42 | **Evaluación**:
43 | 1. Se exige un mínimo de 80% de asistencia al taller. Una vez cumplido, la nota se calcula como se
44 | explica a connuación:
45 | 2. Nota final = 30%*Asistencia + 5%* Informe Preliminar + 65%* Trabajo Final (40% Presentación +
46 | 60% Informe Escrito)
47 |
48 |
49 | **Programación semestre**
50 |
51 | | **Sesión Nº** | **Nombre** | **Tipo Actividad** |
52 | | --- | --- | --- |
53 | |1 | Introducción y motivación al taller. | Clase teórico-práctica Ejemplo de cómo Data Science logra solucionar problemas (Open Street Map yRed de transporte) |
54 | |2| Introducción a Pandas | Clase teórico-práctica Instalación de librería, manejo de objetos y missing values en Pandas. |
55 | |3| Extracción de datasets desde la web | Clase teórico-práctica Extracción de información desde sitios web usando Python + Pandas |
56 | |4| Limpieza de datos con Pandas | Clase teórico-práctica Data Munging. Unión de datasets con Pandas |
57 | |5 | Introducción a la visualización de información | Clase teórico-práctica Introducción a Matplotlib. Gráficos de línea y dispersión. Visualización de errores en gráficos. |
58 | |6 | ¿Cuál es el gráfico correcto para mis datos? | Clase teórico-práctica Gráficos de densidad y contorno.Histogramas. Personalización de figuras. |
59 | | 7 | Visualización de información geoespacial | Clase teórico-práctica Visualización de data con BaseMap (data geográfica) y Seaborn. |
60 | |8 | Ejemplo Práctico I | Clase teórico-práctica Trabajando con la encuesta de viajes(origen-destino), Santiago 2012 |
61 | | 9 | Ejemplo Práctico II | Clase teórico-práctica Trabajando con la encuesta CASEN Entrega de informe preliminar |
62 | | 10 | Sesión final | Clase práctica Presentaciones del trabajo final.Cierre del taller. |
63 |
64 | Este curso está basado en el gran trabajo de Phd. Eduardo Graells (https://github.com/carnby/uddvis)
65 |
--------------------------------------------------------------------------------