drguilhermeapolinario commited on
Commit
fa9ba45
·
verified ·
1 Parent(s): 650dac1

Update data_cleaning.py

Browse files
Files changed (1) hide show
  1. data_cleaning.py +168 -124
data_cleaning.py CHANGED
@@ -1,124 +1,168 @@
1
- import chardet
2
- import pandas as pd
3
- import regex
4
-
5
-
6
- def iniciar(file_path):
7
- """
8
- A function that detects the encoding of a file and reads the file using the detected encoding.
9
-
10
- Parameters:
11
- - file_path (str): The path to the file to be read.
12
-
13
- Returns:
14
- - str: The data read from the file.
15
- """
16
- # Detectar a codificação do arquivo
17
- with open(file_path, "rb") as file:
18
- raw_data = file.read()
19
- result = chardet.detect(raw_data)
20
- encoding = result["encoding"]
21
- print(f"Detected encoding: {encoding}")
22
-
23
- # Ler o arquivo com a codificação detectada
24
- with open(file_path, "r", encoding=encoding) as file:
25
- csv_data = file.read()
26
-
27
- return csv_data
28
-
29
-
30
- def limpa_rci(texto):
31
- """
32
- Cleans up the given text by removing unwanted parts.
33
-
34
- Args:
35
- texto (str): The text to be cleaned.
36
-
37
- Returns:
38
- str: The cleaned text.
39
- """
40
- # Remover partes indesejadas
41
- sub1 = r"(^e-SUS.+\nMIN(.+\n+){7}.+)|((?<=Equipe;)\d+\s\-\s)|(^CBO.+\n(.+\n+){8}.+)|(^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}.+$)|(^Cidadão.+\nDesc.+\nÉ.+\nPossu(.+\n*)*)|(^Não\sinf.+;0.+$)|(;;;;;|;;;;|Ident.+(-|/)\s)|((?<=Saída)\sde.+tro|.+(?=ativos))|"
42
- 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.+$|(?<=Ensino\s[fm][ué][nd]).+(\)|[eat][lso])|(?<=Pré).+\)|(Classe\sde\salfa.+-\s)|((?<=Superior).+rado)|((?<=Alfabet).+\))|(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)"
43
- rx_marc = sub1 + "|" + sub2
44
- # Remover partes indesejadas
45
- texto = regex.sub(rx_marc, "", texto, flags=regex.MULTILINE)
46
-
47
- tira = r"(;;;)"
48
- texto = regex.sub(tira, "", texto, flags=regex.MULTILINE)
49
- tira = r"(;;)"
50
- texto = regex.sub(tira, ";", texto, flags=regex.MULTILINE)
51
- return texto
52
-
53
-
54
- def separa_grupos(texto):
55
- """
56
- A function that uses a regular expression to extract various groups from the input text.
57
-
58
- Args:
59
- texto (str): The input text from which groups are extracted.
60
-
61
- Returns:
62
- dict: A dictionary containing different groups extracted from the text like 'Idade', 'genero', 'cor', 'deficiencia', and 'doencas'.
63
- """
64
- # Expressão regular ajustada para capturar vários grupos
65
- grupos = r"""
66
- ((?P<Data>Data);\d+/\d+/\d+)|
67
- ((?P<Head>[EPCS][aqri][uodí].+;)\w+)|
68
- (?P<Idade>(^Menos.+(?=;0)|^[0-9][0-9]\s\w).+(?=;0))|
69
- (?P<genero>(^(Masc.+|Fem.+)))|
70
- (?P<cor>(^(Bra.+$|Pret.+$|Amar.+$|Par.+$|Indí.+$)))|
71
- (?P<deficiencia>(^(Audi.+a;\d+|Fís.+a;\d+|Cogn.+a;\d+|Vis.+l;\d+\nOut.+$)))|
72
- (?P<doencas>(^(hipert.+al;\d+|diab.+s;\d+|gesta.+e;\d+|acam.+o;\d+|domici.+o;\d+)))
73
- """
74
-
75
- # Compilar a expressão regular com as flags re.VERBOSE e re.MULTILINE para maior legibilidade
76
- pattern = regex.compile(grupos, regex.VERBOSE | regex.MULTILINE)
77
-
78
- matches = pattern.finditer(texto)
79
- grupos_enc = {
80
- "Idade": [],
81
- "genero": [],
82
- "cor": [],
83
- "deficiencia": [],
84
- "doencas": [],
85
- }
86
-
87
- for match in matches:
88
- for group_name, group_value in match.groupdict().items():
89
- if group_value and group_name in grupos_enc:
90
- grupos_enc[group_name].append(group_value)
91
-
92
- return grupos_enc
93
-
94
-
95
- def criar_dataframe(grupos_encontrados):
96
- """
97
- Create dataframes based on the groups found in `grupos_encontrados`.
98
-
99
- Args:
100
- grupos_encontrados (dict): A dictionary containing the groups found and their corresponding values.
101
-
102
- Returns:
103
- dict: A dictionary containing the created dataframes, where the keys are the group names and the values are the corresponding dataframes.
104
- """
105
- dataframes = {}
106
- for grupo, valores in grupos_encontrados.items():
107
- if grupo == "Idade":
108
- df = pd.DataFrame(valores, columns=["Descrição"])
109
- df["Masculino"] = df["Descrição"].apply(lambda x: x.split(";")[1])
110
- df["Feminino"] = df["Descrição"].apply(lambda x: x.split(";")[2])
111
- df["Descrição"] = df["Descrição"].apply(lambda x: x.split(";")[0])
112
- else:
113
- # Tratar casos onde os dados são separados por '\n'
114
- novos_valores = []
115
- for valor in valores:
116
- partes = valor.split("\n")
117
- novos_valores.extend(partes)
118
- df = pd.DataFrame(novos_valores, columns=["Descrição"])
119
- df["Valor"] = df["Descrição"].apply(lambda x: x.split(";")[-1])
120
- df["Descrição"] = df["Descrição"].apply(
121
- lambda x: ";".join(x.split(";")[:-1])
122
- )
123
- dataframes[grupo] = df
124
- return dataframes
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import chardet
2
+ import pandas as pd
3
+ import regex
4
+
5
+ def processar_arquivo(uploaded_file):
6
+ def iniciar(file_path):
7
+ """
8
+ A function that detects the encoding of a file and reads the file using the detected encoding.
9
+ """
10
+ # Detectar a codificação do arquivo
11
+ raw_data = uploaded_file.read()
12
+ result = chardet.detect(raw_data)
13
+ encoding = result["encoding"]
14
+ print(f"Detected encoding: {encoding}")
15
+
16
+ # Ler o arquivo com a codificação detectada
17
+ uploaded_file.seek(0) # Reset file pointer to the beginning
18
+ csv_data = uploaded_file.read().decode(encoding)
19
+ return csv_data
20
+
21
+ def limpa_rci1(texto):
22
+ """
23
+ Cleans up the given text by removing unwanted parts.
24
+ """
25
+ # Remover partes indesejadas
26
+ 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)|"
27
+ 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)"
28
+ rx_marc = sub1 + "|" + sub2
29
+ texto = regex.sub(rx_marc, "", texto, flags=regex.MULTILINE)
30
+ tira = r"(;;;)"
31
+ texto = regex.sub(tira, "", texto, flags=regex.MULTILINE)
32
+ tira = r"(;;)"
33
+ texto = regex.sub(tira, ";", texto, flags=regex.MULTILINE)
34
+ return texto
35
+
36
+ def limpa_rci2(texto):
37
+ """
38
+ Cleans up the given text by removing unwanted parts.
39
+ """
40
+ 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)"
41
+
42
+ texto = regex.sub(sub2, "", texto, flags=regex.MULTILINE)
43
+ tira = r"(;;;)"
44
+ texto = regex.sub(tira, "", texto, flags=regex.MULTILINE)
45
+ tira = r"(;;)"
46
+ texto = regex.sub(tira, "; ", texto, flags=regex.MULTILINE)
47
+ tira = r"(;$)"
48
+ texto = regex.sub(tira, "", texto, flags=regex.MULTILINE)
49
+ tira = r"(\s\d+{10}\s-\s)"
50
+ texto = regex.sub(tira, "", texto, flags=regex.MULTILINE)
51
+ return texto
52
+
53
+ def separa_grupos(texto):
54
+ """
55
+ A function that uses a regular expression to extract various groups from the input text.
56
+ """
57
+ # Expressão regular ajustada para capturar vários grupos
58
+ grupos = r"""
59
+ (?P<Data>(Data;\d+/\d+/\d+))|
60
+ (?P<Head>(Equ.+;.+)|Profiss.+l;\w+|((Saíd.+;\d+)|(Cidadã.+;\d+)))|
61
+ (?P<Idade>(^Menos.+(?=;0)|^[0-9][0-9]\s\w).+(?=;0))|
62
+ (?P<genero>(Masc.+;\d+|Fem.+;\d+))|
63
+ (?P<cor>(^(Bra.+;\d+|Pret.+;\d+|Amar.+;\d+|Par.+;\d+|Indí.+;\d+)))|
64
+ (?P<deficiencia>(^(Audi.+a;\d+|Fís.+a;\d+|Cogn.+a;\d+|Vis.+l;\d+|Out.+;\d+)))|
65
+ (?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+)))|
66
+ (?P<Escola>(Desc.+o;Quant.+\nCre.+e;\d+|Pr.+;\d+|Classe.+;\d+|Ens.+;\d+|Sup.+r;\d+|Alf.+;\d+|Nenhu.+;\d+))|
67
+ (?P<transgen>(Homos.+\);\d+|Bisse.+l;\d+|Hom.+trans.+;\d+|Mul.+trans.+;\d+|Traves.+i;\d+|Transgê.+o;\d+|Não-B.+o;\d+))|
68
+ """
69
+
70
+ # Compilar a expressão regular com as flags re.VERBOSE e re.MULTILINE para maior legibilidade
71
+ pattern = regex.compile(grupos, regex.VERBOSE | regex.MULTILINE)
72
+
73
+ matches = pattern.finditer(texto)
74
+ grupos_enc = {
75
+ "Data": [],
76
+ "Head": [],
77
+ "Idade": [],
78
+ "genero": [],
79
+ "cor": [],
80
+ "deficiencia": [],
81
+ "doencas": [],
82
+ "Escola": [],
83
+ "transgen": []
84
+ }
85
+
86
+ for match in matches:
87
+ for group_name, group_value in match.groupdict().items():
88
+ if group_value and group_name in grupos_enc:
89
+ grupos_enc[group_name].append(group_value)
90
+
91
+ return grupos_enc
92
+
93
+ def criar_dataframe(grupos_encontrados):
94
+ """
95
+ Create dataframes based on the groups found in `grupos_encontrados`.
96
+ """
97
+ dataframes = {}
98
+ for grupo, valores in grupos_encontrados.items():
99
+ if grupo == "Idade":
100
+ df = pd.DataFrame(valores, columns=["Descrição"])
101
+ df["Masculino"] = df["Descrição"].apply(lambda x: x.split(";")[1])
102
+ df["Feminino"] = df["Descrição"].apply(lambda x: x.split(";")[2])
103
+ df["Descrição"] = df["Descrição"].apply(lambda x: x.split(";")[0])
104
+ else:
105
+ # Tratar casos onde os dados são separados por '\n'
106
+ novos_valores = []
107
+ for valor in valores:
108
+ partes = valor.split("\n")
109
+ novos_valores.extend(partes)
110
+ df = pd.DataFrame(novos_valores, columns=["Descrição"])
111
+ df["Valor"] = df["Descrição"].apply(lambda x: x.split(";")[-1])
112
+ df["Descrição"] = df["Descrição"].apply(
113
+ lambda x: ";".join(x.split(";")[:-1]))
114
+ df["Descrição"] = df["Descrição"].apply(lambda x: x.replace(";", ""))
115
+ dataframes[grupo] = df
116
+ return dataframes
117
+
118
+ def renomear_escola(df_escola):
119
+ """
120
+ Renomeia as descrições da coluna 'Descrição' do DataFrame df_escola.
121
+ """
122
+ renomeacoes = {
123
+ "Creche": "Creche",
124
+ "Pré-escola (exceto CA)": "Pré-escola",
125
+ "Classe de alfabetização": "Alfabetização",
126
+ "Ensino fundamental 1ª a 4ª séries": "Fundamental 1ª-4ª",
127
+ "Ensino fundamental 5ª a 8ª séries": "Fundamental 5ª-8ª",
128
+ "Ensino fundamental completo": "Fund. Completo",
129
+ "Ensino fundamental especial": "Fund. Especial",
130
+ "Ensino fundamental EJA - séries iniciais (supletivo 1ª a 4ª)": "Fund. EJA Iniciais",
131
+ "Ensino fundamental EJA - séries finais (supletivo 5ª a 8ª)": "Fund. EJA Finais",
132
+ "Ensino médio, médio 2º ciclo (científico, técnico e etc)": "Médio/Científico/Técnico",
133
+ "Ensino médio especial": "Médio Especial",
134
+ "Ensino médio EJA (supletivo)": "Médio EJA",
135
+ "Alfabetização para adultos (Mobral, etc)": "Alfabetização Adultos",
136
+ "Nenhum": "Nenhum"
137
+ }
138
+
139
+ df_escola["Descrição"] = df_escola["Descrição"].map(renomeacoes)
140
+ return df_escola
141
+
142
+ def limpar_dfs(dataframes, regex_pattern, replacement):
143
+ """
144
+ Aplica uma regex de limpeza em todos os DataFrames.
145
+ """
146
+ for key, df in dataframes.items():
147
+ df["Descrição"] = df["Descrição"].astype(str).apply(lambda x: regex.sub(regex_pattern, replacement, x))
148
+ return dataframes
149
+
150
+ # Leitura e limpeza do arquivo CSV
151
+ csv_data = iniciar(uploaded_file)
152
+ csv_data_limpo = limpa_rci1(csv_data)
153
+
154
+ # Separação dos grupos
155
+ grupos_encontrados = separa_grupos(csv_data_limpo)
156
+
157
+ # Criação dos dataframes
158
+ dataframes = criar_dataframe(grupos_encontrados)
159
+
160
+ # Renomear descrições do DataFrame de escolaridade
161
+ dataframes["Escola"] = renomear_escola(dataframes["Escola"])
162
+
163
+ # Aplicar limpeza final nos DataFrames
164
+ clean_final = r"(\sativ\w+)|(\sde\scid.+o)|(iciê.+ia)|((?<=rans)gên.+o|omem|ulher|ário|Homoss.+\(|\))|(\d{10}\s-\s)"
165
+ substituicao = ""
166
+ dataframes = limpar_dfs(dataframes, clean_final, substituicao)
167
+
168
+ return dataframes