Skip to content

Commit 1ea14a7

Browse files
authored
Otimização do agrupamento do dataframe
Substitui um loop for em Python ineficiente, que fazia append em listas sobre dataframes agrupados do pandas, por uma agregação nativa vetorizada, otimizada em Cython (usando transform('count') e .agg(...))
1 parent 1c3a4bb commit 1ea14a7

1 file changed

Lines changed: 23 additions & 17 deletions

File tree

src/transformacao.py

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -73,23 +73,29 @@ def processar_dados_ipca(
7373
df["Fator"] = 1 + (df["Inflacao_Mensal"] / 100)
7474

7575
logger.info("Realizando consolidação anual e cálculo de fatores compostos...")
76-
resumo_anual = []
77-
for ano, group in df.groupby("Ano"):
78-
# Ignora anos incompletos na base de dados (precisa de exatamente 12 meses)
79-
if len(group) < 12:
80-
logger.info(f"Ignorando o ano {ano} por conter apenas {len(group)} meses.")
81-
continue
82-
83-
media_mensal_ano = group["Inflacao_Mensal"].mean()
84-
acumulado_ano = (group["Fator"].prod() - 1) * 100
85-
86-
resumo_anual.append({
87-
"Ano": int(ano),
88-
"Media_Mensal": round(media_mensal_ano, 4),
89-
"Acumulado_Ano": round(acumulado_ano, 4)
90-
})
91-
92-
df_resumo = pd.DataFrame(resumo_anual)
76+
77+
# Filtra anos incompletos de forma vetorizada
78+
counts = df.groupby("Ano")["Codigo_Mes"].transform("count")
79+
anos_ignorados = df[counts != 12]["Ano"].unique()
80+
81+
if len(anos_ignorados) > 0:
82+
logger.info(f"Anos ignorados por conterem dados incompletos: {list(anos_ignorados)}")
83+
84+
df_valido = df[counts == 12]
85+
86+
# Agregação vetorizada
87+
df_resumo = df_valido.groupby("Ano").agg(
88+
Media_Mensal=("Inflacao_Mensal", "mean"),
89+
Fator_Prod=("Fator", "prod")
90+
).reset_index()
91+
92+
# Calcula o acumulado anual
93+
df_resumo["Acumulado_Ano"] = (df_resumo["Fator_Prod"] - 1) * 100
94+
95+
# Formatação e seleção das colunas desejadas para igualar ao comportamento original
96+
df_resumo["Media_Mensal"] = df_resumo["Media_Mensal"].round(4)
97+
df_resumo["Acumulado_Ano"] = df_resumo["Acumulado_Ano"].round(4)
98+
df_resumo = df_resumo[["Ano", "Media_Mensal", "Acumulado_Ano"]]
9399

94100
if df_resumo.empty:
95101
raise ValueError("Nenhum ano completo (com 12 meses) foi encontrado para processamento.")

0 commit comments

Comments
 (0)