Infra
Infra#
El trabajo se hace sobre los datos del FIUBA-Map, que están en un spreadsheet. Acá hacemos un get, ordenamos los jsons de cada usuario en un dataframe de Pandas, y lo guardamos en un pickle para que el resto de los archivos tengan acceso a la base de datos.
Exporta un pickle con los datos de todas las carreras, para los análisis globales, y un pickle para solo una carrera en particular, para los análisis particulares.
from config import CARRERA, PADRON
from tqdm.notebook import tqdm
import json
import pandas as pd
SHEET_ID = '1b6h2RApBs2xbN6-eGVvxH68EALKDklvS91fb7d_IVz4'
SHEET_TABS = {
'REGISTROS': 2103959160,
'USUARIOS': 102021014,
}
REGISTROS_URL = f'https://docs.google.com/spreadsheets/d/{SHEET_ID}/export?format=csv&gid={SHEET_TABS["REGISTROS"]}'
USUARIOS_URL = f'https://docs.google.com/spreadsheets/d/{SHEET_ID}/export?format=csv&gid={SHEET_TABS["USUARIOS"]}'
# Empezamos cargando todos los datos (los usuarios y los mapas están en dos tablas distintas)
df_registros = pd.read_csv(REGISTROS_URL)
df_registros.drop("Timestamp", axis=1, inplace=True)
df_registros.dropna(inplace=True, how="any")
display(df_registros.dropna().tail(3))
df_usuarios = pd.read_csv(USUARIOS_URL)
df_usuarios.drop("Timestamp", axis=1, inplace=True)
df_usuarios.dropna(inplace=True, how="all")
display(df_usuarios.dropna().sample(3))
Padron | Carrera | Mapa | |
---|---|---|---|
4639 | 10007 | sistemas | {"materias":[{"id":"CBC","nota":0},{"id":"81.0... |
4640 | 99568 | industrial | {"materias":[{"id":"CBC","nota":0},{"id":"81.0... |
4641 | 97589 | quimica | {"materias":[{"id":"CBC","nota":0},{"id":"61.0... |
Padron | Carrera | Orientacion | Final de Carrera | |
---|---|---|---|---|
1263 | 123123 | informatica | Sistemas Distribuidos | tpp |
5398 | <script>alert("a")</script> | informatica | Sistemas Distribuidos | tesis |
388 | 108671 | informatica | Sistemas Distribuidos | tpp |
### Testing purposes: en vez de laburar con toooodos los datos, laburemos sólo con los integrantes del grupo
# df_usuarios = df_usuarios[df_usuarios['Padron'].isin(["100029", "101696", "101109", "0000"])]
# Mergeamos!
df_mergeado = df_usuarios.merge(df_registros)
df_mergeado.dropna().sample(3)
Padron | Carrera | Orientacion | Final de Carrera | Mapa | |
---|---|---|---|---|---|
2273 | 104112 | informatica | Sistemas Distribuidos | tpp | {"materias":[{"id":"CBC","nota":0},{"id":"62.0... |
453 | 108397 | informatica | Sistemas Distribuidos | tesis | {"materias":[{"id":"CBC28","nota":6},{"id":"CB... |
1821 | 110119 | informatica | Gestión Industrial de Sistemas | tesis | {"materias":[{"id":"CBC28","nota":5},{"id":"CB... |
df_mergeado.describe()
Padron | Carrera | Orientacion | Final de Carrera | Mapa | |
---|---|---|---|---|---|
count | 4620 | 4620 | 714 | 1768 | 4620 |
unique | 3842 | 15 | 5 | 2 | 3903 |
top | 4444 | industrial | Sistemas Distribuidos | tpp | {"materias":[{"id":"CBC","nota":0,"cuatri":-1}... |
freq | 13 | 1201 | 307 | 1398 | 158 |
# Ahora, desempaquetamos la columna "Mapa" (un JSON que contiene notas, metadata, de todo...)
# y finalmente lleguemos al df que vamos a usar durante todo el tp
df = df_mergeado
new_df = pd.DataFrame()
for idx in tqdm(df.index):
json_mapa = json.loads(df.loc[idx]['Mapa'])
for k in json_mapa.keys():
if not json_mapa[k]:
continue
if k == "materias":
df_json = pd.json_normalize(json_mapa, k, record_prefix="materia_")
else:
df_json = pd.DataFrame({k: [json_mapa[k]]})
df_json["Padron"] = df.loc[idx]['Padron']
df_json["Carrera"] = df.loc[idx]['Carrera']
new_df = pd.concat([new_df, df_json])
df = df.merge(new_df, how="outer", on=['Padron', 'Carrera'])
df.drop('Mapa', axis=1, inplace=True)
# Hace mucho tiempo, el fiuba map tenia un feature que se llamaba "materia_cuatri" (en vez del nuevo "materia_cuatrimestre")
# En donde el usuario seteaba en cuantos N cuatris iba a cursar X materia, en vez de setear el cuatri exacto
# Como ya no se usa en el upstream, no es lo correcto que lo utilicemos en el análisis de datos
if 'materia_cuatri' in df.columns: df.drop('materia_cuatri', axis=1, inplace=True)
df.sample(3)
Padron | Carrera | Orientacion | Final de Carrera | materia_id | materia_nota | aplazos | materia_cuatrimestre | checkboxes | optativas | |
---|---|---|---|---|---|---|---|---|---|---|
103603 | 99149 | civil | NaN | NaN | 94.01 | 4.0 | NaN | NaN | NaN | NaN |
46661 | 39463898 | civil | NaN | NaN | 81.01 | 4.0 | NaN | NaN | NaN | NaN |
94981 | 99428 | industrial | NaN | tpp | 91.12 | 7.0 | NaN | 2019.5 | NaN | NaN |
# Exportamos todo a un hermoso pickle
df.to_pickle('fiuba-map-data-all.pickle')
# Exportamos sólo la información de la carrera a otro pickle
df[df['Carrera'] == CARRERA].to_pickle('fiuba-map-data.pickle')