forked from PedroPHC25/Trabalho_LP_A1
-
Notifications
You must be signed in to change notification settings - Fork 0
/
df_generator_functions.py
349 lines (260 loc) · 11.3 KB
/
df_generator_functions.py
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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
"""Módulo das funções do "df_generator"
Este módulo contém todas as funções que são chamadas no módulo "df_generator" para a limpeza, manipulação e geração de dataframes para as análises e visualizações.
"""
import pandas as pd
import doctest
# Função para filtrar apenas as colunas necessárias para a análise e visualização
def select_columns(df: pd.DataFrame, columns: list) -> pd.DataFrame:
"""
Filtra colunas desejadas do dataframe e entrega um dataframe apenas com essas colunas.
:param df: DataFrame a ser filtrado
:type df: pandas.DataFrame
:param columns: Lista com os nomes das colunas a serem mantidas
:type columns: list
:return: DataFrame apenas com as colunas especificadas
:rtype: pandas.DataFrame
>>> test_data = {"Nome": ["Ana", "Beatriz", "Carlos"], "Idade": [33, 41, 19], "Estado natal": ["Rio de Janeiro", "São Paulo", "Rio Grande do Sul"]}
>>> df_test = pd.DataFrame(test_data, index = ["A", "B", "C"])
Teste normal
>>> select_columns(df_test, ["Nome", "Estado natal"])
Nome Estado natal
A Ana Rio de Janeiro
B Beatriz São Paulo
C Carlos Rio Grande do Sul
Testes de argumento inválido
>>> select_columns(1, ["Nome", "Estado natal"])
'Argumento(s) inadequado(s)'
>>> select_columns("A", ["Nome", "Estado natal"])
'Argumento(s) inadequado(s)'
Teste de coluna inexistente
>>> select_columns(df_test, ["Nome", "Cidade"])
'Coluna(s) não encontrada(s)'
"""
try:
selected_columns = df[columns]
return selected_columns
except TypeError or IndexError:
return "Argumento(s) inadequado(s)"
except KeyError:
return "Coluna(s) não encontrada(s)"
except:
return "Erro desconhecido"
# Função para resetar o index do dataframe
def reset_index(df: pd.DataFrame) -> pd.DataFrame:
"""
Torna o(s) índice(s) do dataframe colunas e atribui ao índice o numérico padrão.
:param df: DataFrame a ter o índice resetado
:type df: pandas.DataFrame
:return: DataFrame com o índice resetado
:rtype: pandas.DataFrame
>>> test_data = {"Nome": ["Ana", "Beatriz", "Carlos"], "Idade": [33, 41, 19], "Estado natal": ["Rio de Janeiro", "São Paulo", "Rio Grande do Sul"]}
>>> df_test = pd.DataFrame(test_data, index = ["A", "B", "C"])
Teste normal
>>> reset_index(df_test)
index Nome Idade Estado natal
0 A Ana 33 Rio de Janeiro
1 B Beatriz 41 São Paulo
2 C Carlos 19 Rio Grande do Sul
Teste de argumento não dataframe
>>> reset_index(1)
'Argumento não é um dataframe'
"""
try:
df.reset_index(inplace = True)
return df
except AttributeError:
return "Argumento não é um dataframe"
except:
return "Erro desconhecido"
# Função para excluir colunas desnecessárias do dataframe
def not_necessary_columns(df: pd.DataFrame, columns: list) -> pd.DataFrame:
"""
Exclui colunas especificadas de um dataframe.
:param df: DataFrame a ser reduzido
:type df: pandas.DataFrame
:param columns: Lista com os nomes das colunas a serem removidas
:type columns: list
:return: DataFrame sem as colunas especificadas
:rtype: pandas.DataFrame
>>> test_data = {"Nome": ["Ana", "Beatriz", "Carlos"], "Idade": [33, 41, 19], "Estado natal": ["Rio de Janeiro", "São Paulo", "Rio Grande do Sul"]}
>>> df_test = pd.DataFrame(test_data, index = ["A", "B", "C"])
Teste normal
>>> not_necessary_columns(df_test, ["Estado natal"])
Nome Idade
A Ana 33
B Beatriz 41
C Carlos 19
Teste de argumento 'df' não dataframe
>>> not_necessary_columns("A", ["Estado natal"])
"Argumento 'df' não é um dataframe"
Teste de coluna inexistente
>>> not_necessary_columns(df_test, ["Cidade"])
'Coluna(s) não encontrada(s)'
"""
try:
df.drop(columns, axis = 1, inplace = True)
return df
except AttributeError:
return "Argumento 'df' não é um dataframe"
except KeyError:
return "Coluna(s) não encontrada(s)"
except:
return "Erro desconhecido"
# Função que elimina coluna em que todas as células são NA
def delete_columns_na(df: pd.DataFrame)-> pd.DataFrame:
"""
Recebe um dataframe e elimina as colunas em que todos
os valores são NA.
:param df: DataFrame fornecido.
:type df: DataFrame
:return: Retorna outro DataFrame.
A função recebrá um DataFrame e as colunas que tiverem
TODOS os valores com NA serão removidas.
.. warning:: A mudança ocorre `inplace`, ou seja, modifica o dataframe original.
>>> test_data = {"Aluno": ["João", "Maria", "José"],"Curso": ["Economia", "Biologia", "Pedagogia"],"Trancamento do curso": [None, None , None ]}
>>> df_test = pd.DataFrame(test_data, index = ["1", "2", "3"])
Teste normal
>>> delete_columns_na(df_test)
Aluno Curso
1 João Economia
2 Maria Biologia
3 José Pedagogia
>>> delete_columns_na("A")
"Argumento 'df' não é um dataframe"
"""
try:
df.dropna(how = "all", axis = 1, inplace = True)
return df
except AttributeError:
return "Argumento 'df' não é um dataframe"
except:
return "Erro desconhecido"
# Função que coloca as colunas explícitas para análise sobre hospitais públicos, privados e filantrópicos
def formatar_df(df_original: pd.DataFrame,
date: int,
coluna_group1: str, coluna_group2: str,
coluna_num: str) -> pd.DataFrame:
"""
Formatação para extração das informações necesssárias.
:param df_original: DataFrame original.
:type df_original: pd.DataFrame
:param date: Competência das análises, em formato anomês, 202001.
:type date: int
:param coluna_group1: Primeira coluna para o agrupamento.
:type date: str
:param coluna_group2: Segunda coluna para o agrupamento.
:type date: str
:param coluna_group1: Coluna numérica.
:type date: str
:return: Retorna um DataFrame com as colunas formatadas.
:rtype: pd.DataFrame
A função deixa explícita as colunas com as informações
para análise e plotagem do gráfico.
.. warning:: O paramêtro date precisa estar no formato 202001, anomês.
Teste para função formatar
>>> data = {'Data': [202301, 202301, 202301, 202301, 202301, 202301],'Estado': ['SP', 'RJ', 'SP', 'RJ','SP', 'RJ'], 'Tipo_Hospital': ['HOSPITAL_FILANTROPICO', 'HOSPITAL_FILANTROPICO', 'HOSPITAL_PRIVADO', 'HOSPITAL_PRIVADO','HOSPITAL_PUBLICO', 'HOSPITAL_PUBLICO'], 'Valor': [100, 200, 150, 50, 202, 154],"Nome" : ["Hospital Santa Esperança", "Instituto Médico Vital", "Centro Hospitalar Estrela da Manhã", "Hospital São Lucas", "Clínica Médica da Esperança", "Hospital das Crianças Felizes"]}
>>> example = pd.DataFrame(data)
>>> example.set_index(["Data", "Nome"], inplace=True)
>>> formatar_df(example, 202301, 'Estado', 'Tipo_Hospital', 'Valor')
Estado Hospital Filantrópico Hospital Privado Hospital Público
0 SP 100 150 202
1 RJ 200 50 154
"""
# Seleciona os dados na data requerida
df_original = df_original.loc[date]
# Armazena os estados presentes na tabela
estados = df_original[coluna_group1].unique()
# Agrupando por duas colunas e somando uma coluna numérica
df_original = df_original.groupby([coluna_group1, coluna_group2])[coluna_num].sum()
# Criando o novo df com as colunas desejadas
df_formatado = pd.DataFrame(columns=["Estado", "Hospital Filantrópico", "Hospital Privado", "Hospital Público"])
# Iterando para adicionar cada estado e suas estatísticas
for estado in estados:
try:
# Localizando as informações e organizando em colunas
nova_linha = [estado,
df_original.loc[estado].loc["HOSPITAL_FILANTROPICO"],
df_original.loc[estado].loc["HOSPITAL_PRIVADO"],
df_original.loc[estado].loc["HOSPITAL_PUBLICO"]]
# Adicionando a linha criada
df_formatado.loc[len(df_formatado)] = nova_linha
# O estado de Roraima não possui a coluna "Hospital Filatrópico"
except KeyError:
nova_linha = [estado,
0,
df_original.loc[estado].loc["HOSPITAL_PRIVADO"],
df_original.loc[estado].loc["HOSPITAL_PUBLICO"]]
df_formatado.loc[len(df_formatado)] = nova_linha
return df_formatado
def filtra_year(df: pd.DataFrame, período: int )-> pd.DataFrame:
"""
Formatação para extração das informações necesssárias.
:param df: DataFrame original.
:type df: pd.DataFrame
:param período: Competência das análises, em formato anomês, 202001.
:type date: int
:return: Retorna um DataFrame com os dados filtrados pelo período especificado.
:rtype: pd.DataFrame
.. warning:: O paramêtro date precisa estar no formato 202001, anomês.
"""
try:
df_filtrado = df[df["COMP"] == período]
return df_filtrado
except AttributeError:
return "Argumento 'df' não é um dataframe"
except KeyError:
return "Coluna não encontrada"
except:
return "Erro desconhecido"
##GRÁFICO DE BARRAS - LEITOS PEDIÁTRICOS
# Gerando um novo data frame a partir do data
def generate_bar_chart_data(data, group_column, value_column):
"""
Gera os dados para um gráfico de barras a partir de um DataFrame agrupado.
:param data: DataFrame contendo os dados.
:type data: pandas.DataFrame
:param group_column: Nome da coluna para agrupamento.
:type group_column: str
:param value_column: Nome da coluna para os valores.
:type value_column: str
:return: Rótulos e valores para o gráfico de barras.
:rtype: tuple
"""
grouped_data = data.groupby(group_column)[value_column].sum()
labels = grouped_data.index.tolist()
values = grouped_data.values.tolist()
return labels, values
def clean_data(df):
"""
Limpa os dados do DataFrame.
:param df: DataFrame a ser limpo.
:type df: pandas.DataFrame
:return: DataFrame limpo.
:rtype: pandas.DataFrame
# Doctests
>>> data = pd.DataFrame({
... 'coluna1': [1, 2, 3, 4, 5, 6],
... 'coluna2': [None, 2, None, 4, None, 6]
... })
>>> data_limpo = clean_data(data)
>>> data_limpo
coluna1 coluna2
0 1 0.0
1 2 2.0
2 3 0.0
3 4 4.0
4 5 0.0
5 6 6.0
"""
try:
# Remover linhas duplicadas
df = df.drop_duplicates()
# Preencher valores ausentes (NaN)
df = df.fillna(0) # Substitua 0 pelo valor desejado
# Renomear colunas (se necessário)
df = df.rename(columns={'coluna_antiga': 'nova_coluna'})
return df
except Exception as e:
raise e
if __name__ == "__main__":
doctest.testmod(verbose = True)