File size: 8,603 Bytes
fa9ba45
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
import chardet
import pandas as pd
import regex

def processar_arquivo(uploaded_file):
    def iniciar(file_path):
        """
        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>(Data;\d+/\d+/\d+))|
            (?P<Head>(Equ.+;.+)|Profiss.+l;\w+|((Saíd.+;\d+)|(Cidadã.+;\d+)))|
            (?P<Idade>(^Menos.+(?=;0)|^[0-9][0-9]\s\w).+(?=;0))|
            (?P<genero>(Masc.+;\d+|Fem.+;\d+))|
            (?P<cor>(^(Bra.+;\d+|Pret.+;\d+|Amar.+;\d+|Par.+;\d+|Indí.+;\d+)))|
            (?P<deficiencia>(^(Audi.+a;\d+|Fís.+a;\d+|Cogn.+a;\d+|Vis.+l;\d+|Out.+;\d+)))|
            (?P<doencas>(^(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<Escola>(Desc.+o;Quant.+\nCre.+e;\d+|Pr.+;\d+|Classe.+;\d+|Ens.+;\d+|Sup.+r;\d+|Alf.+;\d+|Nenhu.+;\d+))|
            (?P<transgen>(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

    # 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
    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