TP Integrador de Big Data / Data Science
Gustavo Navarro - Comisión 22608 - Enero 2023
Análisis exploratorio
Carga de datos
# las primeras 5 filas
df.head()
#Las últimas filas del dataframe
df.tail()
Resumen estadístico
df.describe()
#Revisar los tipos de datos
df.dtypes
Limpieza y ordenamiento de datos
Encontrar las filas duplicadas
print(f'Original: {df.id.count()} filas')
duplicate_rows_df = df[df.duplicated()]
print(f'Cantidad de filas duplicadas: {duplicate_rows_df.id.count()}')
#Eliminar los duplicados
df = df.drop_duplicates()
#Cantidad de filas despues de eliminar los duplicados
print(f'Final: {df.id.count()} filas')
#Eliminar las columnas irrelevantes
print(df.columns)
df =df.drop(['id'], axis=1)
print(df.columns)
Renombrar las columnas
df = df.rename(columns = {
'gender': 'Gender',
'race/ethnicity': 'Ethnicity',
'parental level of education': 'Parental level of education',
'lunch': 'Lunch',
'employed': 'Employed',
'test preparation course': 'Test preparation course',
'math score': 'Math score',
'physics score': 'Physics score',
'chemistry score': 'Chemistry score',
'algebra_score': 'Algebra score'})
df.columns
Eliminación de valores perdidos o nulos
#Encontrar los valores nulos
print(df.isnull().sum())
#Eliminar los valores perdidos
df = df.dropna()
print()
#Despues de eliminar los nulos
print(df.isnull().sum())
Detectar los valores outliers
sns.boxplot(x=df['Math score'])
plt.show()
sns.boxplot(x=df['Physics score'])
plt.show()
sns.boxplot(x=df['Algebra score'])
plt.show()
sns.boxplot(x=df['Chemistry score'])
plt.show()
print(f'Antes: {df.Lunch.count()} filas\n')
Q1 = df.quantile(0.25)
Q3 = df.quantile(0.75)
IQR = Q3 - Q1
print(IQR)
df = df[~((df < (Q1 - 1.5*IQR)) | (df > (Q3 + 1.5*IQR))).any(axis=1)]
print(f'\nDespues: {df.Lunch.count()} filas')
Visualización de los datos obtenidos
Encontrar correlaciones y frecuencias
plt.hist(df['Algebra score'], bins=20)
plt.title('Algebra')
plt.ylabel('Student count')
plt.xlabel('Score')
plt.show()
plt.hist(df['Chemistry score'], bins=20)
plt.title('Chemistry')
plt.ylabel('Student count')
plt.xlabel('Score')
plt.show()
plt.hist(df['Math score'], bins=20)
plt.title('Math')
plt.ylabel('Student count')
plt.xlabel('Score')
plt.show()
plt.hist(df['Physics score'], bins=20)
plt.title('Physics')
plt.ylabel('Student count')
plt.xlabel('Score')
plt.show()
#Correlacion entre los datos = mapa de calor
c = df.corr()
print(c)
plt.figure(figsize= (20, 10))
sns.heatmap(c, cmap='BrBG', annot=True)
plt.show()
#pandas.value_counts()-> devuelve una serie de valores unicos en un orden descendente de frecuencia
labels = df['Gender'].value_counts().index
sizes = df['Gender'].value_counts()
plt.pie(sizes, labels=labels, autopct='%1.2f%%')
plt.title('Gender')
plt.show()
#Repetimos para Etnia, empleo y el resto de las variables categóricas
labels = df['Ethnicity'].value_counts().index
sizes = df['Ethnicity'].value_counts()
plt.pie(sizes, labels=labels, autopct='%1.2f%%')
plt.title('Ethnicity')
plt.show()
labels = df['Employed'].value_counts().index
sizes = df['Employed'].value_counts()
plt.pie(sizes, labels=labels, autopct='%1.2f%%')
plt.title('Employed')
plt.show()
labels = df['Test preparation course'].value_counts().index
sizes = df['Test preparation course'].value_counts()
plt.pie(sizes, labels=labels, autopct='%1.2f%%')
plt.title('Test preparation course')
plt.show()
labels = df['Parental level of education'].value_counts().index
sizes = df['Parental level of education'].value_counts()
plt.pie(sizes, labels=labels, autopct='%1.2f%%')
plt.title('Parental level of education')
plt.show()
labels = df['Lunch'].value_counts().index
sizes = df['Lunch'].value_counts()
plt.pie(sizes, labels=labels, autopct='%1.2f%%')
plt.title('Lunch')
plt.show()
Respondiendo preguntas
¿Hay alguna relación entre el promedio de notas obtenidas y el hecho de haber realizado el curso preparatorio?
#axis=1 hace que se aplique la función sobre los valores numericos de la fila en vez de las columnas
df['Average score'] = df.mean(axis=1)
df
si = df[df['Test preparation course'] == 'completed']
no = df[df['Test preparation course'] == 'none']
Cantidad de alumnos que hicieron y que no hicieron el curso preparatorio
print('Realizaron el curso:', si['Test preparation course'].count())
print('No realizaron el curso:', no['Test preparation course'].count())
sns.histplot(si['Average score'], color = 'green', alpha= .4, fill = True)
sns.histplot(no['Average score'], color = 'red', alpha= .4, fill = True)
plt.show()
Promedio de notas de los alumnos que hicieron y no hicieron el curso preparatorio
df.drop(['id', 'gender','race/ethnicity', 'parental level of education', 'lunch', 'employed'], axis = 'columns', inplace=True)
df
df =df.round(2)
df
df.groupby(['test preparation course']).mean().round(2)
Conclusión
Si bien la cantidad de alumnos que no realizaron el curso duplicaron a los que si lo hicieron, esta diferencia no se ve reflejada significativamente en el promedio de las notas. Dicha diferencia es entre 5 y 10 puntos según la materia. Lo cual nos indica que no es necesariamente obligatorio el curso preparatorio.
Se recomienda auditar el contenido del curso, a fin de lograr un mejor rendimiento en el nivel académico e incrementar el interés del alumnado.