import chardet import pandas as pd import regex def iniciar(uploaded_file): """ A function that detects the encoding of a file and reads the file using the detected encoding. """ # Detectar a codificação do arquivo raw_data = uploaded_file.read() result = chardet.detect(raw_data) encoding = result["encoding"] print(f"Detected encoding: {encoding}") # Ler o arquivo com a codificação detectada uploaded_file.seek(0) # Reset file pointer to the beginning csv_data = uploaded_file.read().decode(encoding) return csv_data def limpa_rci1(texto): """ Cleans up the given text by removing unwanted parts. """ # Remover partes indesejadas sub1 = r"(^e-SUS.+\nMIN(.+\n+){2}.+)|(^CBO.+\n(.+\n+){2}.+)|(^Não\sinf.+\n+Identif.+\nDes.+\nDes.+\nDes.+\nRes.+\n+Iden.+$)|(^Não\sin.+\n+Ident.+Cor$)|(^Não\sin.+\n+Ident.+\nDesc.+\nBra.+\nNat(.+\n+){34}.+)|(^Inf.+\nDesc.+\nAdult.+\n(.+\n+){10}.+)|(^Inf.+\n(Des.+\n){3}.+$)|(^Inf.+\nDesc.+\n(Tem\salg.+\n){1}.+$)|(^Inf.+\nA\slist.+\nDes(.+\n+){8}.+$)|(^Desc.+\nÉ.+\nPossu(.+\n*)*)|(^Não\sinf.+;0.+$)|(;;;;;|;;;;|Ident.+(-|/)\s)|" sub2 = r"(^C.*(rin|card|resp).+\n.+\n.+[os]\s)|(;;;\nT.+\nT.+$)|(;Sim|(?<=[az];);|\ssabe;|\s.\sEnfisema)|(^Participa.+$|Poss.+de\s|(?<=privado.;\d\d\d);.+|Poss.+de\s|(?<=privado.;\d\d\d\d);.+)|((Desc.+\n){3}Resp.+$)|(Etnia.+\nD.+\nNã.+$)|(Nacio.+\nDesc.+\nB.+\nNat.+\nEst.+$)|(Infor.+\nDesc.+\nCôn(.+\n){31}Inf.+$)|Deseja\sinf.+$|(Infor.+\nDesc.+\nEmpreg(.+\n){10}.+$)|Intelec.+/\s|((Está\s(com\s)?))|(^Condiç.+\nD.+$)|((Faz\suso.+e\s)|PIC;.+|Tem\s|ou\steve\s|Teve\s|internação.+\nUsa\splant.+$|\s/\sderrame|diagnóst.+de\s)" rx_marc = sub1 + "|" + sub2 texto = regex.sub(rx_marc, "", texto, flags=regex.MULTILINE) tira = r"(;;;)" texto = regex.sub(tira, "", texto, flags=regex.MULTILINE) tira = r"(;;)" texto = regex.sub(tira, ";", texto, flags=regex.MULTILINE) return texto def limpa_rci2(texto): """ Cleans up the given text by removing unwanted parts. """ sub2 = r"(^C.*(rin|card|resp).+\n.+\n.+[os]\s)|(;;;\nT.+\nT.+$)|(;Sim|(?<=[az];);|\ssabe;|\s.\sEnfisema)|(\d+{10}\s-\s)|(^Participa.+$|Poss.+de\s|(?<=privado.;\d\d\d);.+|Poss.+de\s|(?<=privado.;\d\d\d\d);.+)|((Desc.+\n){3}Resp.+$)|(Etnia.+\nD.+\nNã.+$)|(Nacio.+\nDesc.+\nB.+\nNat.+\nEst.+$)|(Infor.+\nDesc.+\nCôn(.+\n){31}Inf.+$)|Deseja\sinf.+$|(Infor.+\nDesc.+\nEmpreg(.+\n){10}.+$)|Intelec.+/\s|((Está\s(com\s)?))|(^Condiç.+\nD.+$)|((Faz\suso.+e\s)|PIC;.+|Tem\s|ou\steve\s|Teve\s|internação.+\nUsa\splant.+$|\s/\sderrame|diagnóst.+de\s)" texto = regex.sub(sub2, "", texto, flags=regex.MULTILINE) tira = r"(;;;)" texto = regex.sub(tira, "", texto, flags=regex.MULTILINE) tira = r"(;;)" texto = regex.sub(tira, "; ", texto, flags=regex.MULTILINE) tira = r"(;$)" texto = regex.sub(tira, "", texto, flags=regex.MULTILINE) tira = r"(\s\d+{10}\s-\s)" texto = regex.sub(tira, "", texto, flags=regex.MULTILINE) return texto def separa_grupos(texto): """ A function that uses a regular expression to extract various groups from the input text. """ # Expressão regular ajustada para capturar vários grupos grupos = r""" (?P(Data;\d+/\d+/\d+))| (?P(Equ.+;.+)|Profiss.+l;\w+|((Saíd.+;\d+)|(Cidadã.+;\d+)))| (?P(^Menos.+(?=;0)|^[0-9][0-9]\s\w).+(?=;0))| (?P(Masc.+;\d+|Fem.+;\d+))| (?P(^(Bra.+;\d+|Pret.+;\d+|Amar.+;\d+|Par.+;\d+|Indí.+;\d+)))| (?P(^(Audi.+a;\d+|Fís.+a;\d+|Cogn.+a;\d+|Vis.+l;\d+|Out.+;\d+)))| (?P(^(hipert.+al;\d+|diab.+s;\d+|gesta.+e;\d+|acam.+o;\d+|domici.+o;\d+|fuma.+e;\d+|saú.+e;\d+|Asm.+;\d+|DPO.+;\d+|Insufic.+ca;\d+|Insufic.+al;\d+)))| (?P(Desc.+o;Quant.+\nCre.+e;\d+|Pr.+;\d+|Classe.+;\d+|Ens.+;\d+|Sup.+r;\d+|Alf.+;\d+|Nenhu.+;\d+))| (?P(Homos.+\);\d+|Bisse.+l;\d+|Hom.+trans.+;\d+|Mul.+trans.+;\d+|Traves.+i;\d+|Transgê.+o;\d+|Não-B.+o;\d+))| """ # Compilar a expressão regular com as flags re.VERBOSE e re.MULTILINE para maior legibilidade pattern = regex.compile(grupos, regex.VERBOSE | regex.MULTILINE) matches = pattern.finditer(texto) grupos_enc = { "Data": [], "Head": [], "Idade": [], "genero": [], "cor": [], "deficiencia": [], "doencas": [], "Escola": [], "transgen": [] } for match in matches: for group_name, group_value in match.groupdict().items(): if group_value and group_name in grupos_enc: grupos_enc[group_name].append(group_value) return grupos_enc def criar_dataframe(grupos_encontrados): """ Create dataframes based on the groups found in `grupos_encontrados`. """ dataframes = {} for grupo, valores in grupos_encontrados.items(): if grupo == "Idade": df = pd.DataFrame(valores, columns=["Descrição"]) df["Masculino"] = df["Descrição"].apply(lambda x: x.split(";")[1]) df["Feminino"] = df["Descrição"].apply(lambda x: x.split(";")[2]) df["Descrição"] = df["Descrição"].apply(lambda x: x.split(";")[0]) else: # Tratar casos onde os dados são separados por '\n' novos_valores = [] for valor in valores: partes = valor.split("\n") novos_valores.extend(partes) df = pd.DataFrame(novos_valores, columns=["Descrição"]) df["Valor"] = df["Descrição"].apply(lambda x: x.split(";")[-1]) df["Descrição"] = df["Descrição"].apply( lambda x: ";".join(x.split(";")[:-1])) df["Descrição"] = df["Descrição"].apply(lambda x: x.replace(";", "")) dataframes[grupo] = df return dataframes def renomear_escola(df_escola): """ Renomeia as descrições da coluna 'Descrição' do DataFrame df_escola. """ renomeacoes = { "Creche": "Creche", "Pré-escola (exceto CA)": "Pré-escola", "Classe de alfabetização": "Alfabetização", "Ensino fundamental 1ª a 4ª séries": "Fundamental 1ª-4ª", "Ensino fundamental 5ª a 8ª séries": "Fundamental 5ª-8ª", "Ensino fundamental completo": "Fund. Completo", "Ensino fundamental especial": "Fund. Especial", "Ensino fundamental EJA - séries iniciais (supletivo 1ª a 4ª)": "Fund. EJA Iniciais", "Ensino fundamental EJA - séries finais (supletivo 5ª a 8ª)": "Fund. EJA Finais", "Ensino médio, médio 2º ciclo (científico, técnico e etc)": "Médio/Científico/Técnico", "Ensino médio especial": "Médio Especial", "Ensino médio EJA (supletivo)": "Médio EJA", "Alfabetização para adultos (Mobral, etc)": "Alfabetização Adultos", "Nenhum": "Nenhum" } df_escola["Descrição"] = df_escola["Descrição"].map(renomeacoes) return df_escola def limpar_dfs(dataframes, regex_pattern, replacement): """ Aplica uma regex de limpeza em todos os DataFrames. """ for key, df in dataframes.items(): df["Descrição"] = df["Descrição"].astype(str).apply(lambda x: regex.sub(regex_pattern, replacement, x)) return dataframes def processar_arquivo(uploaded_file): """ Processa o arquivo CSV e retorna os DataFrames. """ # Leitura e limpeza do arquivo CSV csv_data = iniciar(uploaded_file) csv_data_limpo = limpa_rci1(csv_data) # Separação dos grupos grupos_encontrados = separa_grupos(csv_data_limpo) # Criação dos dataframes dataframes = criar_dataframe(grupos_encontrados) # Renomear descrições do DataFrame de escolaridade if "Escola" in dataframes: dataframes["Escola"] = renomear_escola(dataframes["Escola"]) # Aplicar limpeza final nos DataFrames clean_final = r"(\sativ\w+)|(\sde\scid.+o)|(iciê.+ia)|((?<=rans)gên.+o|omem|ulher|ário|Homoss.+\(|\))|(\d{10}\s-\s)" substituicao = "" dataframes = limpar_dfs(dataframes, clean_final, substituicao) return dataframes