<jupyter_start><jupyter_text>Importando as bibliotecas<jupyter_code>import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import statsmodels.formula.api as smf
import seaborn as sns
import random
import scipy.stats
import datetime
pd.set_option("display.max_rows", 18, "display.max_columns", 18)<jupyter_output><empty_output><jupyter_text>Preparando uma base de dados geral<jupyter_code>#verificando a quantidade de dados por arquivo
rows_aluno = sum(1 for line in open('DM_ALUNO.csv')) - 1
rows_curso = sum(1 for line in open('DM_CURSO.csv')) - 1    
rows_docente = sum(1 for line in open('DM_DOCENTE.csv')) - 1   
print(rows_aluno, rows_curso, rows_docente)
#para importar um sample de um df muito grande
colunas_aluno = ['CO_IES','CO_ALUNO','TP_CATEGORIA_ADMINISTRATIVA','TP_SEXO','CO_OCDE_AREA_GERAL','CO_OCDE_AREA_ESPECIFICA','CO_OCDE_AREA_DETALHADA','CO_OCDE','CO_CURSO','NU_ANO_INGRESSO','TP_SITUACAO','NU_ANO_NASCIMENTO','NU_MES_NASCIMENTO','NU_DIA_NASCIMENTO','IN_MATRICULA', 'IN_CONCLUINTE', 'IN_APOIO_SOCIAL', 'IN_BOLSA_ESTAGIO', 'NU_ANO_INGRESSO']
n = sum(1 for line in open('DM_ALUNO.csv')) - 1
s = 1200000 
skip = sorted(random.sample(range(1, n+1), n-s))
#importação com o skip jogando fora o numero de linhas selecionadas aleatoriamente
df_aluno = pd.read_csv('DM_ALUNO.csv', sep="|", skiprows = skip, encoding = "latin1", usecols=colunas_aluno) 
df_aluno

df_aluno.info()
#importando apenas as colunas necessárias do arquivo com os dados dos cursos
colunas_curso = ['CO_IES','DT_INICIO_FUNCIONAMENTO','CO_UF', 'CO_CURSO','CO_OCDE_AREA_GERAL','CO_OCDE_AREA_ESPECIFICA','CO_OCDE_AREA_DETALHADA','CO_OCDE']
df_curso = pd.read_csv('DM_CURSO.CSV', usecols = colunas_curso, sep = "|", encoding='latin1')
df_curso
#importando os dados referentes as UF
df_estado = pd.read_csv('estados.csv', sep=';')
df_estado = df_estado.drop(columns = ['Unnamed: 0'])
df_estado
#importando o df com as informações dos cursos de acordo com a OCDE
df_ocde = pd.read_csv('TB_AUX_AREA_OCDE.CSV', sep="|", engine='python')
df_ocde
# Merge nos df's referentes aos alunos e cursos para uma base geral com dados para todos os alunos
df_curso_completo = pd.merge(df_curso, df_ocde, how='left')
df_curso_completo = pd.merge(df_curso_completo, df_estado, how='left')
df_aluno_completo = pd.merge(df_aluno, df_curso_completo, how='left')
del df_aluno
df_aluno_completo

colunas_docente = ['TP_REGIME_TRABALHO','IN_BOLSA_PESQUISA','IN_ATUACAO_PESQUISA','TP_ESCOLARIDADE','CO_IES','TP_CATEGORIA_ADMINISTRATIVA','CO_DOCENTE']
df_docente = pd.read_csv('DM_DOCENTE.CSV', usecols=colunas_docente, sep="|")
df_docente<jupyter_output><empty_output><jupyter_text>1) Tabelas com número de universidades públicas e privadas por estado e número de alunos por universidade<jupyter_code>lista_ins = {1: 'Pública', 2: 'Pública', 3: 'Pública', 4: 'Privada', 5: 'Privada', 6: 'Privada', 7: 'Privada'}
df_aluno_completo['Pub/Priv'] = df_aluno_completo['TP_CATEGORIA_ADMINISTRATIVA'].map(lista_ins)
df_aluno_completo
group1 = df_aluno_completo.groupby(['NOME_UF', 'Pub/Priv'])
tabela1 = group1.agg({'CO_IES': 'nunique', 'CO_ALUNO': 'nunique'})
tabela1.unstack()<jupyter_output><empty_output><jupyter_text>2) Pergunta-se: é verdade que existe menos mulheres nos cursos de exatas? Explique com os dados.<jupyter_code>df_ocde
# Verificando qual categoria da OCDE se refere a cursos de exatas
group2 = df_ocde.groupby('CO_OCDE_AREA_GERAL')
group2.agg({'NO_OCDE_AREA_GERAL': list})
                         
df_aluno_completo
# filtrando o curso de exatas
prim = df_aluno_completo[df_aluno_completo['CO_OCDE_AREA_GERAL'] > 3]
curso_exatas = prim[prim['CO_OCDE_AREA_GERAL'] < 6]
curso_exatas
# Verificando se o data frame curso_exatas tem apenas as duas categorias de cursos desejadas
curso_exatas.nunique()
# se tratando de um evento binomial, para elucidar melhor a resolução, iremos substituir 2 para 0 na ocorrência de ser homem
curso_exatas['TP_SEXO_B'] = curso_exatas['TP_SEXO'].replace(2, 0)
curso_exatas.drop(['TP_SEXO'], axis =1)
# contagem de mulheres em cursos de exatas
curso_exatas.TP_SEXO_B.value_counts()
# No caso de uma distribuição binominal, a probabilidade de um evento é a própria média
prop_mulheres = 77177/(168860+77177)
prop_mulheres
plt.hist(curso_exatas['TP_SEXO_B'], label = '0 - Homem \n1 - Mulher')
plt.title('Mulheres em curso de exatas')
plt.legend();
# fazendo o teste de hipótese para uma distribuição binomial, sendo que a hipótese nula é de que homens e mulheres tem a mesma
# proporção em cursos de exatas e a alternativa é de que existem menos mulheres em cursos de exatas, ou seja, um teste unicaudal
scipy.stats.binom_test(77177, n=(168860+77177), p=0.5, alternative='less')<jupyter_output><empty_output><jupyter_text>A hipótese nula de que não existe diferença na presença de homens e mulheres em cursos na área de exatas é rejeitada com um nível de confiança de 95%, ja que o p value do teste é menor que 5% ou 0,05 e a hipótese alternativa, de que existem menos mulheres em cursos de exatas é aceita.  3) Quantos cursos novos abrem por ano?<jupyter_code>df_curso_completo
df_curso_completo['DT_INICIO_FUNCIONAMENTO'] = df_curso_completo['DT_INICIO_FUNCIONAMENTO'].astype('str')
df_curso_completo['ANO_FUNC'] = df_curso_completo['DT_INICIO_FUNCIONAMENTO'].apply(lambda x: x[-4:])
df_curso_completo
df_questao3 = df_curso_completo.copy()
questao3 = df_questao3.groupby(['ANO_FUNC'], as_index=False).agg({'CO_CURSO': 'count'})
questao3 = questao3[questao3.ANO_FUNC != 'nan']
questao3['ANO_FUNC'] = questao3['ANO_FUNC'].astype('int')
questao3 = questao3[questao3['ANO_FUNC']>1999]
questao3 = questao3.drop(questao3.index[19])
questao3<jupyter_output><empty_output><jupyter_text>4) Se usarmos a taxa de concluientes de um curso como variável de dificuldade dos cursos, eles tem ficado mais faceis ou mais duros ao longo do tempo? Quais as dificuldades para uma afirmação dessas?<jupyter_code>df_aluno_completo
df_questao4 = df_aluno_completo[['CO_CURSO', 'CO_ALUNO', 'NU_ANO_INGRESSO', 'IN_CONCLUINTE']]
df_questao4
teste = df_questao4.groupby(['CO_CURSO', 'NU_ANO_INGRESSO'], as_index=False).agg({'IN_CONCLUINTE': 'mean', 'CO_ALUNO': 'count'}) #rodar depois
teste
teste2 = teste[teste['CO_ALUNO']>10]
teste2 = teste2[teste2['NU_ANO_INGRESSO']>2000]
teste2 = teste2.round(2)
teste2

teste3 = teste2.groupby(['CO_CURSO', 'NU_ANO_INGRESSO']).agg({'IN_CONCLUINTE': list})
teste3.unstack()
cond1 = teste2['CO_CURSO'] == 5001384
df_graph1 = teste2.loc[(cond1)]
fig, ax = plt.subplots(1,1)
x = df_graph1['NU_ANO_INGRESSO']
y = df_graph1['IN_CONCLUINTE']
plt.title('Taxa de concluintes de por ano - curso 5001384')
plt.bar(x,y, color = 'pink');<jupyter_output><empty_output><jupyter_text>5) Rode uma regressão multipla que explique o abandono dos cursos, será que professores mais/menos preparados influência nessas taxas?<jupyter_code># calculando uma média de instrução para os docentes de cada IES
docente_ies = df_docente.groupby(['CO_IES'])
media_docente = docente_ies.agg({'TP_ESCOLARIDADE': 'mean'})
media_docente.reset_index(inplace = True)
media_docente
df_aluno_5 = pd.read_csv('DM_ALUNO.csv', sep="|", skiprows = skip, encoding = "latin1") 
df_aluno_5
df_aluno_5 = pd.merge(df_aluno_5, media_docente, how='left')
df_aluno_5.corr().round(2)['TP_SITUACAO'].sort_values(ascending=False)
teste_questao5 = df_aluno_5[['CO_IES', 'TP_SITUACAO', 'IN_CONCLUINTE', 'QT_CARGA_HORARIA_INTEG', 'TP_MOBILIDADE_ACADEMICA_INTERN', 'IN_APOIO_SOCIAL', 'IN_INGRESSO_TOTAL', 'TP_ESCOLARIDADE']]
teste_questao5
lista_st = {2: 'normal', 3: 'abandono', 4: 'abandono', 5: 'abandono', 6: 'normal', 7: 'normal'}
lista_st2 = {'normal': 0, 'abandono': 1}
lista_st3 = {1: 'sim', 2: 'sim'}
lista_st4 = {'sim': 1}
teste_questao5['situacao'] = teste_questao5['TP_SITUACAO'].map(lista_st)
teste_questao5['TX_ABANDONO'] = teste_questao5['situacao'].map(lista_st2)
teste_questao5['intercambio'] = teste_questao5['TP_MOBILIDADE_ACADEMICA_INTERN'].map(lista_st3)
teste_questao5['TX_INTERCAMBIO'] = teste_questao5['intercambio'].map(lista_st4)
teste_questao5
questao5 = teste_questao5.groupby(['CO_IES'], as_index=False).agg({'IN_CONCLUINTE': 'mean', 'QT_CARGA_HORARIA_INTEG': 'mean', 'TP_ESCOLARIDADE': 'mean', 'TX_INTERCAMBIO': 'mean', 'IN_APOIO_SOCIAL': 'mean', 'IN_INGRESSO_TOTAL': 'mean', 'TX_ABANDONO': 'mean' })
questao5
questao5 = questao5.fillna(0)

questao5['TX_INTERCAMBIO_DUMMY'] = questao5['TX_INTERCAMBIO'].apply(lambda x: 1 if x>0.5 else 0)
questao5 = pd.get_dummies(questao5, columns =['TX_INTERCAMBIO_DUMMY'])
questao5
questao5['TX_ABANDONO_LOG'] = np.log1p(questao5['TX_ABANDONO'])
questao5['IN_APOIO_SOCIAL_LOG'] = np.log1p(questao5['IN_APOIO_SOCIAL'])
questao5['TP_ESCOLARIDADE_LOG'] = np.log1p(questao5['TP_ESCOLARIDADE'])
questao5['IN_INGRESSO_TOTAL_LOG'] = np.log1p(questao5['IN_INGRESSO_TOTAL'])
questao5['QT_CARGA_HORARIA_INTEG_LOG'] = np.log1p(questao5['QT_CARGA_HORARIA_INTEG'])
questao5['IN_CONCLUINTE_LOG'] = np.log1p(questao5['IN_CONCLUINTE'])
questao5
questao5.corr()
regressao5 = questao5[['TX_ABANDONO_LOG', 'IN_APOIO_SOCIAL_LOG', 'TP_ESCOLARIDADE_LOG', 'IN_INGRESSO_TOTAL_LOG', 'QT_CARGA_HORARIA_INTEG_LOG', 'IN_CONCLUINTE_LOG', 'TX_INTERCAMBIO_DUMMY_0', 'TX_INTERCAMBIO_DUMMY_1']]
regressao5
sns.pairplot(data=regressao5)
#rodando a regressão

function = 'TX_ABANDONO_LOG ~ IN_APOIO_SOCIAL_LOG + IN_INGRESSO_TOTAL_LOG + QT_CARGA_HORARIA_INTEG_LOG + IN_CONCLUINTE_LOG + TP_ESCOLARIDADE_LOG + TX_INTERCAMBIO_DUMMY_0 + TX_INTERCAMBIO_DUMMY_1'
model = smf.ols(formula=function, data=regressao5).fit()
model.summary()<jupyter_output><empty_output><jupyter_text>6) Quais os cursos com maior crescimento de matriculas por região? E quais os com maior queda? Como você explicaria isso.<jupyter_code>df_aluno_completo
df_questao6 =df_aluno_completo.copy()
questao6 = df_questao6[df_questao6['NU_ANO_INGRESSO']>2000]
questao6 = questao6.groupby(['Região', 'NO_OCDE'])['IN_MATRICULA'].agg(['sum', 'count']).reset_index([0,1])
questao6['tx_matricula'] = questao6['sum'] / questao6['count']
questao6.sort_values(by=['Região','sum','tx_matricula'],ascending=False, inplace=True)
questao6 = questao6[questao6['count']>100]
questao6
maiores = []
menores = []
for reg in questao6['Região'].unique():
    t = questao6.loc[questao6['Região']==reg]
    M = t.nlargest (5, columns=['tx_matricula'])
    m = t.nsmallest(5, columns=['tx_matricula'])
    maiores.append(M)
    menores.append(m)
lista1 = pd.concat(maiores).sort_values(by=['Região','tx_matricula'], ascending = False)
lista2 = pd.concat(menores).sort_values(by=['Região','tx_matricula'], ascending = False)

pd.set_option("display.max_rows", 25)
lista1
pd.set_option("display.max_rows", 25)
lista2<jupyter_output><empty_output><jupyter_text>7) Construa uma variável "Signo" dos estudantes e explique porque ela é correlacionada com a variável "probabilidade de formação" (construir)<jupyter_code>idx = pd.date_range('2018-01-01', periods=365, freq='D')
ts = pd.Series(range(len(idx)), index=idx)
teste7 = pd.DataFrame(ts)
teste7 = datas.reset_index()
teste7 = datas.rename(columns={'index':'anomesdia'})
teste7 = datas.rename(columns={'0':'fora'})
teste7['anomesdia'] = teste7['anomesdia'].astype('str')
signos = []
cap = 'Capricornio'
aq = 'Aquario'
pe = 'Peixes'
ar = 'Aries'
to = 'Touro'
ge = 'Gemeos'
ca = 'Cancer'
le = 'Leao'
vi = 'Virgem'
li = 'Libra'
es = 'Escorpiao'
sa = 'Sagitario'

for x in teste7['anomesdia']:
    if x > '01-01' and x < '01-21':
        signos.append(cap)
    elif x > '01-21'and x < '02-20':
        signos.append(aq)
    elif x > '02-19' and x < '03-21':
        signos.append(pe)
    elif x > '03-20' and x < '04-21':
        signos.append(ar)
    elif x > '04-20' and x < '05-21':
        signos.append(to)
    elif x > '05-20' and x < '06-21':
        signos.append(ge)
    elif x > '06-20' and x < '07-22':
        signos.append(ca)
    elif x > '07-21' and x < '08-23':
        signos.append(le)
    elif x > '08-22' and x < '09-23':
        signos.append(vi)
    elif x > '09-22' and x < '10-23':
        signos.append(li)
    elif x > '10-22' and x < '11-22':
        signos.append(es)
    elif x > '11-21' and x < '12-22':
        signos.append(sa)
    else:
        signos.append(cap)
teste7['signo'] = signos    
teste7['anomesdia'] = teste7['anomesdia'].apply(lambda x: x[-5:])
teste7 = teste7[['anomesdia', 'signo']]
teste7 = pd.DataFrame(teste7)
teste7.nunique()
df_aluno7 = df_aluno_completo.copy()
df_aluno7['NU_ANO_NASCIMENTO'] = df_aluno7['NU_ANO_NASCIMENTO'].astype('str')
df_aluno7['NU_MES_NASCIMENTO'] = df_aluno7['NU_MES_NASCIMENTO'].astype('str')
df_aluno7['NU_DIA_NASCIMENTO'] = df_aluno7['NU_DIA_NASCIMENTO'].astype('str')
df_aluno7['data_nasc'] = df_aluno7['NU_ANO_NASCIMENTO']+'-'+df_aluno7['NU_MES_NASCIMENTO']+'-'+df_aluno7['NU_DIA_NASCIMENTO']
df_aluno7['data_nasc'] = pd.to_datetime(df_aluno7['data_nasc'])
df_aluno7['data_nasc'] = df_aluno7['data_nasc'].astype('str')
df_aluno7['data_signo'] = df_aluno7['data_nasc'].apply(lambda x: x[-5:])
df_aluno7 = pd.merge(df_aluno7, teste7, how='left', left_on=['data_signo'] , right_on=['anomesdia'])
df_aluno7
df_aluno7.drop(['diames','anomesdia'])
df_aluno7<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.14191193246634726, 'fraction_numerical': 0.03209369533804852, 'mean_word_length': 7.102279728897104, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '13788', 'license': 'MIT', 'n_tokens_mistral': 5894, 'n_tokens_neox': 5625, 'n_words': 1020, 'path': 'desafio2_alana.ipynb', 'repo_name': 'Grupo-DH/Desafios', 'size': '13149'}