#!/usr/bin/env python # coding: utf-8 # # Bienvenides # # En esta notebook vamos a levantar un archivo con las respuestas de algun cuatrimestre del cursito de python de la FIFA con Pandas, y vamos también a trabajarlo un poco para ver qué tipo de cosas se pueden hacer y qué información sacar de los datos # In[171]: import pandas as pd import numpy as np import matplotlib.pyplot as plt import datetime get_ipython().run_line_magic('matplotlib', 'notebook') respuestas = pd.read_csv("respuestas.csv") respuestas # Es un poco molesto de ver asi la tabla, porque cada horario tiene mucha información que estaba en el form, pero ya no nos sirve, entones podemos reemplazar cada turno por algo mas corto, así como tambien cambiar las preguntas que también son muy largas. # In[172]: respuestas.columns = ['Tiempo', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Nivel', 'Extras'] respuestas.replace({'Mañana\(1030-1330\)': 'Man', 'Tarde\(1330-1630\)': 'Tar', 'Noche\(1730-2030\)': 'Noc', 'Ninguna':"None"}, regex=True, inplace=True) respuestas # --- # --- # Algo trivial de hacer ahora es ver, por ejemplo, la distribución de nivel de la gente que está viniendo al taller. Esto puede servir para enfocar de diferentes maneras los temas que vamos a dar. O bien super básicos, o si podemos apretar más el acelerador y dar mas cosas. # In[176]: # Agrego el '_ =' solo para que no me printee una cosa las notebooks, porque la funcion `hist` # devuelve algunos parametros (pueden ver cuales haciendo `plt.hist?`) y por ahora no los necesito # asi que le digo que ni los guarde _ = plt.hist(respuestas.Nivel,bins=list(range(1, 12)), align='left', edgecolor='k', color='lightblue') plt.xlabel("Nivel") plt.ylabel("# de personas") # --- # --- # # Supongan que nos interesa saber qué dia se anotaron mas personas, o a qué hora. Por ejemplo para saber cuándo hacer algún posteo en una red social, o lo que sea. Podemos hacerlo viendo el campo de `Time` que devuelve el formulario, que tiene las fechas y horas de cada envío de respuesta. # In[170]: # Traigo las fechas, y las paso a un tipo de dato datetime asi matplotlib lo plotea bien y no hace ruido dates = [datetime.datetime.strptime(date_str, '%d/%m/%Y %H:%M:%S') for date_str in respuestas.Tiempo.values] # Ordeno las fechas por si alguna se mezcló en el camino, y ploteo contra el id. # en realidad solo necesito que vaya de uno en uno con cada fecha de ingreso # sería lo mismo hacer algo como: # plt.plot(sorted(dates), list(range(len(dates)))) plt.plot(sorted(dates), respuestas.index+1) plt.xticks(rotation=45) # Arreglo para que no se solapen las horas plt.ylabel("Respuestas al form") plt.grid() # --- # --- # Algo menos trivial sería ver como es el solape de inscripciones, para saber como distribuirnos los docentes los horarios. Si hay mucha gente a la mañana habrá que poner más gente en ese turno. Pero también es importante saber cuanta gente se anotó a mas de un turno, porque quizás se podría eliminar alguno de los turnos y distribuir a esa gente en los otros. # # Una rudimentaria forma de hacerlo sería recorrer cada uno de los dias y horarios para cada alumno e ir almacenando la id de ese alumno, cosa de que poder ver fácilmente quien se anotó a qué dia y horario # In[153]: dias = respuestas.columns[1:6].values solape = {} turnos = ['Man', 'Tar', 'Noc', 'None'] # Solape va a ser un diccionario con 5 entradas (una por cada dia) # cada entrada va a tener otras tres (una por cada turno) # y ahi guardaremos el id de la persona que se anotó a ese dia y horario # # Sería una cosa: # Lun: # Man: {Persona1, ...} # Tar: {Persona25, ...} # Noc: {...} # None: {...} # # idem con los demas días # # Primero entonces inicializo todo vacio, pero para que ya esté la estructura armada for dia in dias: solape[dia] = {turn:set() for turn in turnos} for index, fila in respuestas.iterrows(): # recorro todas las filas for dia in dias: # recorro todos los dias (que son las columnas 1:6) for turno in fila[dia].split(", "): # Aca me fijo y separo todos los dias que se anotó la persona solape[dia][turno].add(str(index)) # agrego a la persona a cada dia y turno apropiado # Ahora tenemos en `solape` todo distribuido ya con las personas ordenadas en los dias y turnos que eligió. Para ver efectivamente el solapamiento de horarios podemos ver la interseccion de cada set, justamente por este motivo es que elegimos usar un set, para poder intersecar fácilmente. # In[154]: for dia in dias: # Voy a armar una "matriz de solape" por dia print(f"{dia}:") print(" \t","\t".join(turnos)) # Esta es la primer fila con los nombre de los turnos for turno_i in turnos: print(turno_i, end='\t') # La primer columna con nombres de turnos for turno_j in turnos: # Aca interseco los dos sets con `&` y luego me fijo el largo del set # como son sets, no tengo que preocuparme por doble conteos nunca!! interseccion = len(solape[dia][turno_i] & solape[dia][turno_j]) print(f"{interseccion}", end='\t') # printeo el valor y meto un tab print("") # agrego una linea en blanco print("\n\n") # Y bueno, así de fácil (fácil?) se pudo saber como es la distribución de inscriptos en cada horario, y cómo fue el solapamiento de turnos. Obvio que esto tambien se podría visualizar en un heatmap, o algo por el estilo, pero todas esas cosas extra se las dejamos para ustedes para experimentar. # # Esto puede parecer al pedo, pero quizas está bueno por si realmente se decide en base a estos datos sacar un turno. Por ejemplo, si se decide eliminar el turno tarde del Lunes, se le podría enviar un mail a aquellos que se anotaron a la tarde y noche, pidiendoles que se anoten de noche, y a los que se anotaron mañana-tarde que se anoten a la mañana! # # Abajo les dejamos eso hecho con el id del inscripto. El formulario tambien nos dice a nosotros sus mails, pero no divulgaríamos esa informacion! De cualquier manera el procedimiento sería el mismo, salvo que al final printeariamos los mails de forma tal de luego poder copiar y pegarlos y enviarles el mail a todos juntos. # In[194]: gente_man_tar = respuestas.loc[(respuestas.Lun == 'Man, Tar')] gente_man_tar # Aca si estuviera el campo Email podriamos hacer # print(gente_man_tar[Email]) # Y mandarles el mail