Ruptura_Projetada/Lançamentos/Script_lançamento_boti_v2.ipynb
2025-06-20 11:22:28 -03:00

1785 lines
54 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"id": "6ad35669",
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np \n",
"import glob\n",
"import os \n",
"from datetime import datetime"
]
},
{
"cell_type": "code",
"execution_count": 2,
"id": "fa16d50c",
"metadata": {},
"outputs": [],
"source": [
"hoje = datetime.today().strftime('%Y-%m-%d')"
]
},
{
"cell_type": "code",
"execution_count": 3,
"id": "9fcdc77a",
"metadata": {},
"outputs": [],
"source": [
"calendario = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BASE DE DADOS LANÇAMENTO\\BOT\\CICLO 9\\CALENDARIO_CICLO\\Ciclo_Expandido_com_Datas.xlsx\")\n",
"\n",
"calendario['Date'] = pd.to_datetime(calendario['Date'])\n",
"\n",
"# Get today (normalized to midnight)\n",
"today = pd.Timestamp(\"today\").normalize()\n",
"\n",
"calendario['NUM_CICLO'] = calendario['Ciclo'].str[-2:].astype(int)\n",
"\n",
"calendario['ANO_CICLO'] = calendario['Ciclo'].str[0:5]\n",
"\n",
"calendario = calendario[calendario['MARCA'] == \"BOTICARIO\"]\n",
"\n",
"calendario['CICLOMAIS2'] = calendario['ANO_CICLO'].astype(str) + (calendario['NUM_CICLO'].astype(int) + 3).astype(str).str.zfill(2) #<<< MUDAR O \"4\" (CICLO ATUAL + 4 PARA ACHAR O CICLO DA SUGESTÃO) EX: C202505 -> C202509\n",
"ciclo_mais2 = calendario[calendario['Date'].dt.normalize() == today]['CICLOMAIS2'].iloc[0]\n",
"\n",
"# Filter rows where date matches today\n",
"filtered_calendario = calendario[calendario['Ciclo'] == ciclo_mais2][:1]\n",
"\n",
"filtered_calendario['dias_ate_inicio'] = filtered_calendario['INICIO CICLO'].iloc[0] - today\n",
"\n",
"filtered_calendario['dias_ate_inicio'] = filtered_calendario['dias_ate_inicio'].dt.days.astype(int)\n",
"\n",
"filtered_calendario['match'] = 1\n"
]
},
{
"cell_type": "code",
"execution_count": 4,
"id": "bbec229d",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Ciclo</th>\n",
" <th>INICIO CICLO</th>\n",
" <th>FIM CICLO</th>\n",
" <th>DURAÇÃO</th>\n",
" <th>MARCA</th>\n",
" <th>Date</th>\n",
" <th>NUM_CICLO</th>\n",
" <th>ANO_CICLO</th>\n",
" <th>CICLOMAIS2</th>\n",
" <th>dias_ate_inicio</th>\n",
" <th>match</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2283</th>\n",
" <td>C202512</td>\n",
" <td>2025-08-11</td>\n",
" <td>2025-08-31</td>\n",
" <td>21</td>\n",
" <td>BOTICARIO</td>\n",
" <td>2025-08-11</td>\n",
" <td>12</td>\n",
" <td>C2025</td>\n",
" <td>C202515</td>\n",
" <td>55</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Ciclo INICIO CICLO FIM CICLO DURAÇÃO MARCA Date \\\n",
"2283 C202512 2025-08-11 2025-08-31 21 BOTICARIO 2025-08-11 \n",
"\n",
" NUM_CICLO ANO_CICLO CICLOMAIS2 dias_ate_inicio match \n",
"2283 12 C2025 C202515 55 1 "
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"filtered_calendario"
]
},
{
"cell_type": "code",
"execution_count": 5,
"id": "0245ed28",
"metadata": {},
"outputs": [],
"source": [
"ciclo_lanc = filtered_calendario['Ciclo'].max()"
]
},
{
"cell_type": "code",
"execution_count": 6,
"id": "7a3c1e6f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'C202512'"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"ciclo_lanc"
]
},
{
"cell_type": "code",
"execution_count": 7,
"id": "61ffc777",
"metadata": {},
"outputs": [],
"source": [
"df_similares = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C12\\LANÇAMENTOS\\arquivos para geração da sugestão\\SIMILARES\\PRODUTOS SIMILARES - BOT.xlsx\")\n",
"\n",
"df_similares = pd.merge(left=df_similares,right=calendario[['Ciclo','INICIO CICLO','FIM CICLO','DURAÇÃO']], how= 'left', left_on = 'CICLO SIMILAR',right_on = 'Ciclo' )\n",
"\n",
"df_similares = df_similares.drop(columns=['Ciclo'])\n",
"\n",
"df_similares = df_similares.rename(columns={'INICIO CICLO':'INICIO CICLO SIMILAR','FIM CICLO':'FIM CICLO SIMILAR','DURAÇÃO':'DURAÇÃO CICLO SIMILAR'})\n",
"df_similares.drop_duplicates(inplace=True)\n",
"\n",
"df_similares['MATCH'] = 1\n",
"\n",
"df_similares = df_similares.drop(columns=['INICIO DO CICLO',\n",
" 'FIM DO CICLO', 'DURAÇÃO CICLO','INICIO CICLO SIMILAR','FIM CICLO SIMILAR','DURAÇÃO CICLO SIMILAR'])"
]
},
{
"cell_type": "code",
"execution_count": 8,
"id": "99ea95e6",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['PRODUTO LANÇAMENTO', 'DESCRIÇÃO DO LANÇAMENTO', 'PRODUTO SIMILAR',\n",
" 'DESCRIÇÃO SIMILAR', 'CICLO SIMILAR', 'FOCO', 'IAF', 'CATEGORIA',\n",
" 'MARCA', '% CONSUMIDOR', 'MECANICA CONSUMIDOR', '% REVENDEDOR',\n",
" 'MECANICA REVENDEDOR', 'TIPO DE PRODUTO', 'MATCH'],\n",
" dtype='object')"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_similares.columns"
]
},
{
"cell_type": "code",
"execution_count": 9,
"id": "fe922f62",
"metadata": {},
"outputs": [],
"source": [
"df_tabela = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C12\\LANÇAMENTOS\\arquivos para geração da sugestão\\TABELA DE PEDIDO\\Pedidos Semanais Especiais - BOT - 202512.xlsx\")\n",
"\n",
"df_tabela = df_tabela[df_tabela['Região'] == 'NNE'] \n",
"\n",
"df_tabela = df_tabela[(df_tabela['Canal'] != 'Ecomm') | (df_tabela['Canal'] != 'Ecomm | VD') | (df_tabela['Canal'] != 'Ecomm | Loja')] \n",
"\n",
"df_tabela['Canal'] = np.where((df_tabela['Canal'] == \"Loja\") | (df_tabela['Canal'] == \"Todos\") | (df_tabela['Canal'] == \"Loja | VD\"),\"TODOS\",\"VD\")\n",
"\n",
"df_tabela = df_tabela[df_tabela['Tipo de promoção'].str.contains('Lançamentos', na=False)]"
]
},
{
"cell_type": "code",
"execution_count": 10,
"id": "e0c55962",
"metadata": {},
"outputs": [],
"source": [
"df_pdv = pd.read_excel(r\"C:\\Users\\joao.herculano\\Documents\\PDV_ATT.xlsx\")\n",
"\n",
"df_pdv_origi = pd.read_excel(r\"C:\\Users\\joao.herculano\\Documents\\PDV_ATT.xlsx\")"
]
},
{
"cell_type": "code",
"execution_count": 11,
"id": "a3a045d9",
"metadata": {},
"outputs": [],
"source": [
"\n",
"\n",
"df_pdv = df_pdv.rename(columns={'DESCRIÇÃO':'DESCRIÇÃO PDV'})\n",
"\n",
"df_pdv = df_pdv.drop(columns=['REGIÃO', 'ESTADO','CIDADE','GESTÃO','MARCA'])\n",
"\n",
"df_pdv['UF'] = np.where(df_pdv['UF'] == 'VDC','BA',df_pdv['UF'])\n",
"\n",
"#ignorando a PDV que ainda não está online\n",
"df_pdv = df_pdv[df_pdv['DESCRIÇÃO PDV'] != '23813-COMERCIO-HIB VALENTE']\n",
"\n",
"df_pdv = df_pdv[df_pdv['STATUS'] != \"INATIVO\"]\n",
"\n",
"df_pdv = df_pdv[df_pdv['STATUS'] != \"MATRIZ\"]\n",
"\n",
"df_pdv = df_pdv[df_pdv['SUPERVISOR'] != 'Inativa']\n",
"\n",
"df_pdv['MATCH'] = 1"
]
},
{
"cell_type": "code",
"execution_count": 12,
"id": "df04a501",
"metadata": {},
"outputs": [],
"source": [
"df_similares = pd.merge(left=df_similares,right=df_pdv,right_on=['MATCH'],left_on=['MATCH'],how='inner')\n",
"\n",
"df_similares = df_similares.drop_duplicates()"
]
},
{
"cell_type": "code",
"execution_count": 13,
"id": "0da911af",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_37548\\2509858446.py:10: DtypeWarning: Columns (6,7) have mixed types. Specify dtype option on import or set low_memory=False.\n",
" df_draft = pd.concat([pd.read_csv(file) for file in csv_files], ignore_index=True)\n"
]
},
{
"data": {
"text/plain": [
"(130656, 47)"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Caminho onde estão as subpastas com os arquivos CSV\n",
"\n",
"# Set the path to the folder containing CSV files\n",
"folder_path = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C12\\LANÇAMENTOS\\arquivos para geração da sugestão\\DRAFT\" # arquivo dos drafts\n",
"\n",
"# Pattern to match all CSV files\n",
"csv_files = glob.glob(os.path.join(folder_path, '*.csv'))\n",
"\n",
"# Read and concat all CSVs\n",
"df_draft = pd.concat([pd.read_csv(file) for file in csv_files], ignore_index=True)\n",
"\n",
"df_draft['match'] = 1 \n",
"\n",
"df_draft.shape\n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"id": "0c8c7493",
"metadata": {},
"outputs": [],
"source": [
"df_draft = df_draft.drop(columns=['Categoria'])"
]
},
{
"cell_type": "code",
"execution_count": 15,
"id": "91298cde",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['Histórico de Vendas do Ciclo 202409',\n",
" 'Histórico de Vendas do Ciclo 202410',\n",
" 'Histórico de Vendas do Ciclo 202411',\n",
" 'Histórico de Vendas do Ciclo 202412',\n",
" 'Histórico de Vendas do Ciclo 202413',\n",
" 'Histórico de Vendas do Ciclo 202414',\n",
" 'Histórico de Vendas do Ciclo 202415',\n",
" 'Histórico de Vendas do Ciclo 202416',\n",
" 'Histórico de Vendas do Ciclo 202417',\n",
" 'Histórico de Vendas do Ciclo 202501',\n",
" 'Histórico de Vendas do Ciclo 202502',\n",
" 'Histórico de Vendas do Ciclo 202503',\n",
" 'Histórico de Vendas do Ciclo 202504',\n",
" 'Histórico de Vendas do Ciclo 202505',\n",
" 'Histórico de Vendas do Ciclo 202506',\n",
" 'Histórico de Vendas do Ciclo 202507',\n",
" 'Histórico de Vendas do Ciclo 202508',\n",
" 'Histórico de Vendas do Ciclo Atual'],\n",
" dtype='object')"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_draft.columns[7:25]"
]
},
{
"cell_type": "code",
"execution_count": 16,
"id": "34e179cb",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_37548\\1463083786.py:24: DeprecationWarning: DataFrameGroupBy.apply operated on the grouping columns. This behavior is deprecated, and in a future version of pandas the grouping columns will be excluded from the operation. Either pass `include_groups=False` to exclude the groupings or explicitly select the grouping columns after groupby to silence this warning.\n",
" crescimento_por_pdv = df_draft.groupby('PDV').apply(calcular_crescimento)\n"
]
}
],
"source": [
"# Define as colunas mensais\n",
"colunas_mensais = df_draft.columns[7:25]\n",
"\n",
"# Agrupa por PDV e calcula crescimento médio por PDV\n",
"def calcular_crescimento(grupo):\n",
" soma_mensal = grupo[colunas_mensais].sum() # soma por mês\n",
" variacao_mensal = soma_mensal.pct_change().dropna() # variação percentual mês a mês\n",
" variacao_mensal = variacao_mensal[np.isfinite(variacao_mensal)]\n",
"\n",
" if len(variacao_mensal) == 0:\n",
" return pd.Series({'CRESCIMENTO': np.nan})\n",
"\n",
" media = variacao_mensal.mean()\n",
" desvio = variacao_mensal.std()\n",
"\n",
" limite_sup = media + 2 * desvio\n",
" limite_inf = media - 2 * desvio\n",
"\n",
" variacoes_filtradas = variacao_mensal[variacao_mensal.between(limite_inf, limite_sup)]\n",
" crescimento = round(variacoes_filtradas.mean(), 4)\n",
" return pd.Series({'CRESCIMENTO': crescimento})\n",
"\n",
"# Aplica a função por PDV\n",
"crescimento_por_pdv = df_draft.groupby('PDV').apply(calcular_crescimento)\n",
"\n",
"# Merge do resultado de volta no dataframe original\n",
"df_draft = df_draft.merge(crescimento_por_pdv, on='PDV', how='left')\n"
]
},
{
"cell_type": "code",
"execution_count": 17,
"id": "4bc8c2b4",
"metadata": {},
"outputs": [],
"source": [
"df_similares['PDV'] = df_similares['PDV'].astype('Int64')\n",
"\n",
"df_final = pd.merge(left=df_similares,right=df_draft,right_on=['PDV', 'SKU'],left_on=['PDV','PRODUTO SIMILAR'],how='left')"
]
},
{
"cell_type": "code",
"execution_count": 18,
"id": "c1451562",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(17025, 14)"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_venda_diaria = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C12\\LANÇAMENTOS\\arquivos para geração da sugestão\\VENDAS_DIARIAS\\FormFiltroConsultaVendaSintetica_17_06_2025_14_04_40.xls\")\n",
"df_venda_diaria.shape"
]
},
{
"cell_type": "code",
"execution_count": 19,
"id": "882e68aa",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['Unidade de Negócio', 'Ano', 'Mês', 'Dia', 'Código do Produto',\n",
" 'Descrição do Produto', 'Quantidade', 'Valor Bruto', 'Valor Desconto',\n",
" 'Valor Líquido', 'Valor Vale Troca', 'Líquido - Troca', 'Estoque Atual',\n",
" 'Estoque Mínimo'],\n",
" dtype='object')"
]
},
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_venda_diaria.columns"
]
},
{
"cell_type": "code",
"execution_count": 20,
"id": "c7ddaf20",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(17025, 16)"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_venda_diaria['PDV'] = df_venda_diaria['Unidade de Negócio'].str.split(\"-\").str[0].str.strip()\n",
"\n",
"df_venda_diaria['Dia'] = pd.to_datetime(df_venda_diaria['Dia'], format='%d/%m/%Y')\n",
"\n",
"df_venda_diaria = pd.merge(left=df_venda_diaria,right=calendario[['Ciclo','Date']],left_on='Dia',right_on='Date',how='inner')\n",
"\n",
"df_venda_diaria = df_venda_diaria.drop(columns='Date')\n",
"\n",
"df_venda_diaria.shape"
]
},
{
"cell_type": "code",
"execution_count": 21,
"id": "7119556a",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(17025, 17)"
]
},
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# 'Dia' já está em formato datetime, então renomeamos para 'Data' diretamente\n",
"# ou apenas usamos 'Dia' como referência de data\n",
"\n",
"# Ordena o DataFrame para garantir que a cumulativa funcione corretamente\n",
"df_venda_diaria = df_venda_diaria.sort_values(by=['Unidade de Negócio', 'Código do Produto', 'Dia'])\n",
"\n",
"# Calcula a quantidade acumulada até o dia para cada grupo\n",
"df_venda_diaria['Quantidade Acumulada'] = (\n",
" df_venda_diaria\n",
" .groupby(['Unidade de Negócio', 'Código do Produto'])['Quantidade']\n",
" .cumsum()\n",
") # acumulado por grupo até a data da linha\n",
"\n",
"df_venda_diaria.shape"
]
},
{
"cell_type": "code",
"execution_count": 22,
"id": "c707a1b6",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>PDV</th>\n",
" <th>Código do Produto</th>\n",
" <th>Ciclo</th>\n",
" <th>Quantidade Acumulada</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>12522</td>\n",
" <td>4522</td>\n",
" <td>C202312</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>12522</td>\n",
" <td>4522</td>\n",
" <td>C202314</td>\n",
" <td>2</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>12522</td>\n",
" <td>4522</td>\n",
" <td>C202406</td>\n",
" <td>3</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>12522</td>\n",
" <td>4522</td>\n",
" <td>C202407</td>\n",
" <td>4</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>12522</td>\n",
" <td>4522</td>\n",
" <td>C202410</td>\n",
" <td>5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>...</th>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" <td>...</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5800</th>\n",
" <td>5699</td>\n",
" <td>81054</td>\n",
" <td>C202503</td>\n",
" <td>167</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5801</th>\n",
" <td>5699</td>\n",
" <td>81054</td>\n",
" <td>C202504</td>\n",
" <td>168</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5802</th>\n",
" <td>5699</td>\n",
" <td>81054</td>\n",
" <td>C202505</td>\n",
" <td>169</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5803</th>\n",
" <td>5699</td>\n",
" <td>81054</td>\n",
" <td>C202506</td>\n",
" <td>170</td>\n",
" </tr>\n",
" <tr>\n",
" <th>5804</th>\n",
" <td>5699</td>\n",
" <td>85293</td>\n",
" <td>C202506</td>\n",
" <td>5</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5805 rows × 4 columns</p>\n",
"</div>"
],
"text/plain": [
" PDV Código do Produto Ciclo Quantidade Acumulada\n",
"0 12522 4522 C202312 1\n",
"1 12522 4522 C202314 2\n",
"2 12522 4522 C202406 3\n",
"3 12522 4522 C202407 4\n",
"4 12522 4522 C202410 5\n",
"... ... ... ... ...\n",
"5800 5699 81054 C202503 167\n",
"5801 5699 81054 C202504 168\n",
"5802 5699 81054 C202505 169\n",
"5803 5699 81054 C202506 170\n",
"5804 5699 85293 C202506 5\n",
"\n",
"[5805 rows x 4 columns]"
]
},
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_venda_diaria = df_venda_diaria.drop_duplicates()\n",
"\n",
"df_venda_agrupado = df_venda_diaria.fillna(0).groupby(['PDV', 'Código do Produto','Ciclo'])['Quantidade Acumulada'].max().reset_index()\n",
"df_venda_agrupado"
]
},
{
"cell_type": "code",
"execution_count": 23,
"id": "083ff829",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>PDV</th>\n",
" <th>Código do Produto</th>\n",
" <th>Ciclo</th>\n",
" <th>Quantidade Acumulada</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>2955</th>\n",
" <td>20994</td>\n",
" <td>81054</td>\n",
" <td>C202213</td>\n",
" <td>35</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" PDV Código do Produto Ciclo Quantidade Acumulada\n",
"2955 20994 81054 C202213 35"
]
},
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_venda_agrupado[(df_venda_agrupado['Ciclo']=='C202213')&(df_venda_agrupado['Código do Produto']==81054)&(df_venda_agrupado['PDV']=='20994')]"
]
},
{
"cell_type": "code",
"execution_count": 24,
"id": "59707396",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Ciclo object\n",
"Código do Produto int64\n",
"PDV object\n",
"dtype: object"
]
},
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_venda_agrupado[['Ciclo','Código do Produto','PDV']].dtypes"
]
},
{
"cell_type": "code",
"execution_count": 25,
"id": "bdf6abbb",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"CICLO SIMILAR object\n",
"PRODUTO SIMILAR float64\n",
"PDV Int64\n",
"dtype: object"
]
},
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final[['CICLO SIMILAR','PRODUTO SIMILAR','PDV']].dtypes"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "dc452c72",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(1216, 76)"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final = pd.merge(left=df_final, right=filtered_calendario[['Ciclo','INICIO CICLO','FIM CICLO','DURAÇÃO','match','dias_ate_inicio']], right_on='match',left_on='MATCH',how='left')\n",
"df_final.shape"
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "c260e0e3",
"metadata": {},
"outputs": [],
"source": [
"#df_final = df_final.drop(columns=['PDV DESC','status','SKU','Descrição','Lançamento','Item analisado','Planograma','Quantidade por caixa'])"
]
},
{
"cell_type": "code",
"execution_count": 28,
"id": "8a05450c",
"metadata": {},
"outputs": [],
"source": [
"df_final = pd.merge(left=df_final, right=calendario[['Ciclo','INICIO CICLO','FIM CICLO','DURAÇÃO']], right_on='Ciclo',left_on='CICLO SIMILAR',how='left')\n",
"df_final.shape\n",
"\n",
"df_final = df_final.drop_duplicates()"
]
},
{
"cell_type": "code",
"execution_count": 29,
"id": "cc65edab",
"metadata": {},
"outputs": [],
"source": [
"\n",
"df_venda_agrupado = df_venda_agrupado.rename(columns={'Quantidade Acumulada':'Vendas Ciclo Lançamento'})"
]
},
{
"cell_type": "code",
"execution_count": 30,
"id": "c5cd5f42",
"metadata": {},
"outputs": [],
"source": [
"df_final['PRODUTO SIMILAR'] = df_final['PRODUTO SIMILAR'].astype('Int64')\n",
"\n",
"df_venda_agrupado['PDV'] = df_venda_agrupado['PDV'].astype('Int64')\n",
"\n",
"df_final = pd.merge(left=df_final, right = df_venda_agrupado, right_on=['Ciclo','Código do Produto','PDV'],left_on=['CICLO SIMILAR','PRODUTO SIMILAR','PDV'],how='left')\n",
"\n",
"df_final = df_final.drop_duplicates()"
]
},
{
"cell_type": "code",
"execution_count": 31,
"id": "aea3e9a8",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"np.float64(3757.0)"
]
},
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final['Vendas Ciclo Lançamento'].sum()"
]
},
{
"cell_type": "code",
"execution_count": 32,
"id": "bde12ed6",
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final[df_final['PRODUTO LANÇAMENTO'].notna()]\n",
"df_final['Vendas Ciclo Lançamento'] = df_final['Vendas Ciclo Lançamento'].fillna(0)\n"
]
},
{
"cell_type": "code",
"execution_count": 33,
"id": "69c88d20",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"np.int64(14)"
]
},
"execution_count": 33,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final['PDV'].value_counts().min()"
]
},
{
"cell_type": "code",
"execution_count": 34,
"id": "f5206f50",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['Desativação', 'Histórico de Vendas do Ciclo 202409',\n",
" 'Histórico de Vendas do Ciclo 202410',\n",
" 'Histórico de Vendas do Ciclo 202411',\n",
" 'Histórico de Vendas do Ciclo 202412',\n",
" 'Histórico de Vendas do Ciclo 202413',\n",
" 'Histórico de Vendas do Ciclo 202414',\n",
" 'Histórico de Vendas do Ciclo 202415',\n",
" 'Histórico de Vendas do Ciclo 202416',\n",
" 'Histórico de Vendas do Ciclo 202417',\n",
" 'Histórico de Vendas do Ciclo 202501',\n",
" 'Histórico de Vendas do Ciclo 202502',\n",
" 'Histórico de Vendas do Ciclo 202503',\n",
" 'Histórico de Vendas do Ciclo 202504',\n",
" 'Histórico de Vendas do Ciclo 202505',\n",
" 'Histórico de Vendas do Ciclo 202506',\n",
" 'Histórico de Vendas do Ciclo 202507'],\n",
" dtype='object')"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final.columns[29:46]"
]
},
{
"cell_type": "code",
"execution_count": 35,
"id": "5e33d293",
"metadata": {},
"outputs": [],
"source": [
"df_jacobina = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\REGIÃO JACOBINA\\draft unificado.xlsx\")"
]
},
{
"cell_type": "code",
"execution_count": 36,
"id": "4d23ff5a",
"metadata": {},
"outputs": [],
"source": [
"df_jacobina = df_jacobina[['PDV', 'SKU','202408', '202409',\n",
" '202410', '202411', '202412', '202413', '202414', '202415', '202416',\n",
" '202417', '202501', '202502', '202503', '202504', '202505', '202506',\n",
" '202507']]"
]
},
{
"cell_type": "code",
"execution_count": 37,
"id": "5adc5831",
"metadata": {},
"outputs": [],
"source": [
"ciclos = [\n",
" '202408', '202409', '202410', '202411', '202412', '202413',\n",
" '202414', '202415', '202416', '202417', '202501', '202502',\n",
" '202503', '202504', '202505', '202506', '202507']\n",
"\n",
"df_jacobina[ciclos] = df_jacobina[ciclos].fillna(0)"
]
},
{
"cell_type": "code",
"execution_count": 38,
"id": "1c4f5d9d",
"metadata": {},
"outputs": [],
"source": [
"df_final = pd.merge(left=df_final,right=df_jacobina,left_on=['PRODUTO SIMILAR','PDV'],right_on=['SKU','PDV'],how='left')"
]
},
{
"cell_type": "code",
"execution_count": 39,
"id": "2529e624",
"metadata": {},
"outputs": [],
"source": [
"# Gera pares de colunas: coluna estática ↔ coluna de histórico\n",
"pares_validos = [\n",
" (ciclo, f'Histórico de Vendas do Ciclo {ciclo}')\n",
" for ciclo in ciclos\n",
" if ciclo in df_final.columns and f'Histórico de Vendas do Ciclo {ciclo}' in df_final.columns\n",
"]\n",
"\n",
"# Separa os nomes das colunas\n",
"colunas_estaticas = [c[0] for c in pares_validos]\n",
"colunas_historico = [c[1] for c in pares_validos]\n",
"\n",
"# Aplica a regra: se valor na coluna estática for maior, sobrescreve no histórico\n",
"for col_estatica, col_hist in zip(colunas_estaticas, colunas_historico):\n",
" df_final[col_hist] = df_final[col_estatica].where(\n",
" df_final[col_estatica] > df_final[col_hist],\n",
" df_final[col_hist]\n",
" )\n"
]
},
{
"cell_type": "code",
"execution_count": 40,
"id": "0a1bb832",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_37548\\1328364976.py:8: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n",
" variacao_mensal = soma_mensal.pct_change()\n"
]
},
{
"data": {
"text/plain": [
"np.float64(0.1817)"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Suponha que os meses estão nas colunas 10 a 26 (17 colunas = 17 meses)\n",
"colunas_mensais = df_final.columns[29:46]\n",
"\n",
"# Passo 1: Soma todas as linhas (itens) por mês → resultado: total por mês\n",
"soma_mensal = df_final[colunas_mensais].sum()\n",
"\n",
"# Passo 2: Calcula a variação percentual de um mês para o outro\n",
"variacao_mensal = soma_mensal.pct_change()\n",
"variacao_mensal = variacao_mensal.dropna()\n",
"\n",
"variacao_mensal = variacao_mensal[np.isfinite(variacao_mensal)]\n",
"\n",
"# Passo 3: Calcula a média da variação (ignorando o primeiro NaN)\n",
"media_variacao = variacao_mensal[1:].mean()\n",
"\n",
"# Calcula média e desvio padrão\n",
"media = variacao_mensal.mean()\n",
"desvio = variacao_mensal.std()\n",
"\n",
"# Define limite (ex: 2 desvios padrão)\n",
"limite_superior = media + 2 * desvio\n",
"limite_inferior = media - 2 * desvio\n",
"\n",
"# Filtra dados dentro do limite\n",
"filtro = variacao_mensal.between(limite_inferior, limite_superior)\n",
"df_filtrado = variacao_mensal[filtro]\n",
"CRESCIMENTO = round(df_filtrado.mean(),4)\n",
"\n",
"df_final['CRESCIMENTO_GERAL'] = CRESCIMENTO\n",
"\n",
"CRESCIMENTO\n"
]
},
{
"cell_type": "code",
"execution_count": 41,
"id": "a9647c32",
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final.drop(columns='Ciclo_y')\n",
"\n",
"df_final = df_final.rename(columns={'Ciclo_x': 'Ciclo',\t'INICIO CICLO_x': 'INICIO CICLO',\t'FIM CICLO_x':'FIM CICLO' ,'DURAÇÃO_x':'DURAÇÃO',\n",
" \t'INICIO CICLO_y': 'INICIO CICLO SIMILAR' ,\t'FIM CICLO_y': 'FIM CICLO SIMILAR','DURAÇÃO_y':'DURAÇÃO CICLO SIMILAR'})"
]
},
{
"cell_type": "code",
"execution_count": 42,
"id": "b107e519",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['Histórico de Vendas do Ciclo 202502',\n",
" 'Histórico de Vendas do Ciclo 202503',\n",
" 'Histórico de Vendas do Ciclo 202504',\n",
" 'Histórico de Vendas do Ciclo 202505',\n",
" 'Histórico de Vendas do Ciclo 202506',\n",
" 'Histórico de Vendas do Ciclo 202507',\n",
" 'Histórico de Vendas do Ciclo 202508'],\n",
" dtype='object')"
]
},
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final.columns[40:47]"
]
},
{
"cell_type": "code",
"execution_count": 43,
"id": "8290853c",
"metadata": {},
"outputs": [],
"source": [
"VENDA_SIMILAR_6_MESES= df_final.columns[40:47]\n",
"\n",
"df_final['Pico Vendas Similar Ultimos 6 ciclos'] = df_final[VENDA_SIMILAR_6_MESES].max(axis=1)\n",
"\n",
"df_final['Pico Vendas Similar Ultimos 6 ciclos'] = df_final['Pico Vendas Similar Ultimos 6 ciclos'].fillna(0)\n",
"\n",
"df_final['MEDIANA DO HISTÓRICO'] = df_final[colunas_mensais].median(axis=1, skipna=True)\n",
"\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 44,
"id": "d8b30560",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0 1.0\n",
"1 3.5\n",
"2 0.5\n",
"3 0.0\n",
"4 1.0\n",
" ... \n",
"1059 0.0\n",
"1060 0.0\n",
"1061 0.0\n",
"1062 0.0\n",
"1063 0.0\n",
"Length: 1064, dtype: object"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final[colunas_mensais].median(axis=1, skipna=True)\n"
]
},
{
"cell_type": "code",
"execution_count": 45,
"id": "07f043f2",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>CANAL</th>\n",
" <th>med_por_canal</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>CD</td>\n",
" <td>20.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>HIB</td>\n",
" <td>2.0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>LJ</td>\n",
" <td>3.5</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>VD</td>\n",
" <td>10.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" CANAL med_por_canal\n",
"0 CD 20.0\n",
"1 HIB 2.0\n",
"2 LJ 3.5\n",
"3 VD 10.0"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"medi = df_final.groupby(['CANAL'])['MEDIANA DO HISTÓRICO'].max().reset_index()\n",
"medi = medi.rename(columns={'MEDIANA DO HISTÓRICO':'med_por_canal'})\n",
"medi"
]
},
{
"cell_type": "code",
"execution_count": 46,
"id": "94abddce",
"metadata": {},
"outputs": [],
"source": [
"df_final = pd.merge(left=df_final, right=medi,on='CANAL',how='inner')\n"
]
},
{
"cell_type": "code",
"execution_count": 47,
"id": "09cc2f82",
"metadata": {},
"outputs": [],
"source": [
"df_vdc = pd.read_csv(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C11\\arquivos para geração da sugestão\\VENDAS VDC\\vendas_vdc22.02.csv\")\n",
"\n",
"\n",
"\n",
"df_vdc['DATA VENDA'] = pd.to_datetime(df_vdc['DATA VENDA'])\n",
"\n",
"# 'Dia' já está em formato datetime, então renomeamos para 'Data' diretamente\n",
"# ou apenas usamos 'Dia' como referência de data\n",
"\n",
"# Ordena o DataFrame para garantir que a cumulativa funcione corretamente\n",
"df_venda_diaria = df_venda_diaria.sort_values(by=['Unidade de Negócio', 'Código do Produto', 'Dia'])\n",
"\n",
"# Calcula a quantidade acumulada até o dia para cada grupo\n",
"df_vdc['Quantidade Acumulada vdc'] = (\n",
" df_vdc\n",
" .groupby(['PDVDEPARA.Practico', 'Código'])['Soma de Quantidade']\n",
" .cumsum()\n",
") # acumulado por grupo até a data da linha"
]
},
{
"cell_type": "code",
"execution_count": 48,
"id": "5a827c08",
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>PDVDEPARA.Practico</th>\n",
" <th>Código</th>\n",
" <th>Ciclo vdc</th>\n",
" <th>Quantidade Acumulada vdc</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>0</th>\n",
" <td>23701</td>\n",
" <td>48617</td>\n",
" <td>C202212</td>\n",
" <td>6</td>\n",
" </tr>\n",
" <tr>\n",
" <th>1</th>\n",
" <td>23701</td>\n",
" <td>48617</td>\n",
" <td>C202213</td>\n",
" <td>8</td>\n",
" </tr>\n",
" <tr>\n",
" <th>2</th>\n",
" <td>23701</td>\n",
" <td>48617</td>\n",
" <td>C202214</td>\n",
" <td>10</td>\n",
" </tr>\n",
" <tr>\n",
" <th>3</th>\n",
" <td>23701</td>\n",
" <td>48617</td>\n",
" <td>C202215</td>\n",
" <td>12</td>\n",
" </tr>\n",
" <tr>\n",
" <th>4</th>\n",
" <td>23701</td>\n",
" <td>48617</td>\n",
" <td>C202216</td>\n",
" <td>22</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" PDVDEPARA.Practico Código Ciclo vdc Quantidade Acumulada vdc\n",
"0 23701 48617 C202212 6\n",
"1 23701 48617 C202213 8\n",
"2 23701 48617 C202214 10\n",
"3 23701 48617 C202215 12\n",
"4 23701 48617 C202216 22"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_vdc = pd.merge(left=df_vdc,right=calendario[['Date','Ciclo']],left_on='DATA VENDA',right_on='Date',how='inner')\n",
"\n",
"df_vdc_agrupado = df_vdc.groupby(['PDVDEPARA.Practico',\t'Código','Ciclo'])['Quantidade Acumulada vdc'].max().reset_index()\n",
"\n",
"df_vdc_agrupado = df_vdc_agrupado.rename(columns={'Ciclo':'Ciclo vdc'})\n",
"\n",
"\n",
"df_vdc_agrupado.head()"
]
},
{
"cell_type": "code",
"execution_count": 49,
"id": "8ec14143",
"metadata": {},
"outputs": [],
"source": [
"df_final = pd.merge(left=df_final, right = df_vdc_agrupado, right_on=['Ciclo vdc','Código','PDVDEPARA.Practico'],left_on=['CICLO SIMILAR','PRODUTO SIMILAR','PDV'],how='left')\n",
"\n",
"df_final['Quantidade Acumulada vdc'] = df_final['Quantidade Acumulada vdc'].fillna(0)\n",
"\n",
"\n",
"df_final['Vendas Ciclo Lançamento'] = np.where(df_final['Quantidade Acumulada vdc'] > 0, df_final['Quantidade Acumulada vdc'], df_final['Vendas Ciclo Lançamento'])\n",
"\n",
"df_final = df_final.drop(columns='Quantidade Acumulada vdc')\n",
"\n",
"\n",
"df_final = df_final.drop(columns='Ciclo vdc')\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 50,
"id": "1a625e69",
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_37548\\2817892533.py:10: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n",
" df_final['MEDIANA DO HISTÓRICO'] = df_final['MEDIANA DO HISTÓRICO'].fillna(0)\n",
"C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_37548\\2817892533.py:19: FutureWarning: Downcasting object dtype arrays on .fillna, .ffill, .bfill is deprecated and will change in a future version. Call result.infer_objects(copy=False) instead. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`\n",
" df_final['MEDIANA DO HISTÓRICO'] = df_final['MEDIANA DO HISTÓRICO'].fillna(0)\n"
]
},
{
"data": {
"text/plain": [
"(1022, 108)"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"# Cálculo do crescimento\n",
"crescimento_final = df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO']\n",
"crescimento_final = crescimento_final.clip(lower=0.2, upper=0.8) # limita entre 0 e 0.8\n",
"df_final['CRESCIMENTO_FINAL'] = crescimento_final\n",
"\n",
"df_final['CRESCIMENTO_FINAL'] = np.where(df_final['CRESCIMENTO_FINAL'].isna(),df_final['CRESCIMENTO_GERAL'],df_final['CRESCIMENTO_FINAL'])\n",
"\n",
"df_final['CRESCIMENTO_FINAL'] = df_final['CRESCIMENTO_FINAL'].fillna(0)\n",
"\n",
"df_final['MEDIANA DO HISTÓRICO'] = df_final['MEDIANA DO HISTÓRICO'].fillna(0)\n",
"\n",
"# Corrige mediana do histórico onde for zero\n",
"df_final['MEDIANA DO HISTÓRICO'] = np.where(\n",
" df_final['MEDIANA DO HISTÓRICO'] == 0,\n",
" df_final['med_por_canal'],\n",
" df_final['MEDIANA DO HISTÓRICO']\n",
")\n",
"\n",
"df_final['MEDIANA DO HISTÓRICO'] = df_final['MEDIANA DO HISTÓRICO'].fillna(0)\n",
"\n",
"\n",
"\n",
"# Cálculo do PV GINSENG\n",
"pv_crescimento = (df_final['CRESCIMENTO_FINAL']+1) * df_final['Vendas Ciclo Lançamento']\n",
"pv_mediana = (df_final['CRESCIMENTO_FINAL'] + 1) * df_final['MEDIANA DO HISTÓRICO']\n",
"\n",
"df_final['PV GINSENG'] = np.where(\n",
" pv_crescimento < df_final['MEDIANA DO HISTÓRICO'],\n",
" pv_mediana.round(0),\n",
" pv_crescimento.round(0)\n",
")\n",
"\n",
"# Se PV GINSENG for NA, substitui pela média por canal\n",
"df_final['PV GINSENG'] = df_final['PV GINSENG'].fillna(df_final['med_por_canal'].round(0))\n",
"\n",
"df_final['PV GINSENG'] = df_final['PV GINSENG'].round(0).astype(int)\n",
"\n",
"df_final.shape\n"
]
},
{
"cell_type": "code",
"execution_count": 51,
"id": "cfdae71d",
"metadata": {},
"outputs": [],
"source": [
"df_final.to_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C12\\LANÇAMENTOS\\validação.xlsx\",index=False)"
]
},
{
"cell_type": "code",
"execution_count": 52,
"id": "7b058db6",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['Histórico de Vendas do Ciclo 202409',\n",
" 'Histórico de Vendas do Ciclo 202410',\n",
" 'Histórico de Vendas do Ciclo 202411',\n",
" 'Histórico de Vendas do Ciclo 202412',\n",
" 'Histórico de Vendas do Ciclo 202413',\n",
" 'Histórico de Vendas do Ciclo 202414',\n",
" 'Histórico de Vendas do Ciclo 202415',\n",
" 'Histórico de Vendas do Ciclo 202416',\n",
" 'Histórico de Vendas do Ciclo 202417',\n",
" 'Histórico de Vendas do Ciclo 202501',\n",
" 'Histórico de Vendas do Ciclo 202502',\n",
" 'Histórico de Vendas do Ciclo 202503',\n",
" 'Histórico de Vendas do Ciclo 202504'],\n",
" dtype='object')"
]
},
"execution_count": 52,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final.columns[30:43]"
]
},
{
"cell_type": "code",
"execution_count": 53,
"id": "ad10c069",
"metadata": {},
"outputs": [],
"source": [
"df_final.drop(columns=df_final.columns[30:43],inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": 54,
"id": "15b7149f",
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final.rename(columns={df_final.columns[30]: \"C-4\", df_final.columns[31]: \"C-3\",df_final.columns[32]: \"C-2\",df_final.columns[33]: \"C-1\",df_final.columns[34]:'VENDAS CICLO ATUAL'})\n"
]
},
{
"cell_type": "code",
"execution_count": 55,
"id": "9333bc77",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"Index(['PRODUTO LANÇAMENTO', 'DESCRIÇÃO DO LANÇAMENTO', 'PRODUTO SIMILAR',\n",
" 'DESCRIÇÃO SIMILAR', 'CICLO SIMILAR', 'FOCO', 'IAF', 'CATEGORIA',\n",
" 'MARCA', '% CONSUMIDOR', 'MECANICA CONSUMIDOR', '% REVENDEDOR',\n",
" 'MECANICA REVENDEDOR', 'TIPO DE PRODUTO', 'MATCH', 'PDV',\n",
" 'PDV COMO TEXTO', 'CANAL', 'DESCRIÇÃO PDV', 'PDV DESC', 'UF',\n",
" 'ANALISTA', 'SUPERVISOR', 'STATUS', 'CLASSE', 'SKU_X', 'DESCRIÇÃO',\n",
" 'SUBCATEGORIA', 'LANÇAMENTO', 'DESATIVAÇÃO', 'C-4', 'C-3', 'C-2', 'C-1',\n",
" 'VENDAS CICLO ATUAL', 'DIAS SEM VENDA', 'PROJEÇÃO PRÓXIMO CICLO',\n",
" 'PROJEÇÃO PRÓXIMO CICLO + 1', 'PROMOÇÃO PRÓXIMO CICLO',\n",
" 'PROMOÇÃO PRÓXIMO CICLO + 1', 'ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO',\n",
" 'PEDIDO PENDENTE', 'COMPRA INTELIGENTE SEMANAL/SUGESTÃO DE COMPRA',\n",
" 'COMPRA INTELIGENTE PRÓXIMO CICLO',\n",
" 'COMPRA INTELIGENTE PRÓXIMO CICLO + 1', 'ITEM DESATIVADO',\n",
" 'DATA PREVISTA REGULARIZAÇÃO', 'CARTEIRA BLOQUEADA PARA NOVOS PEDIDOS',\n",
" 'PLANOGRAMA', 'QUANTIDADE POR CAIXA', 'PREÇO SELL IN', 'QUANTIDADE',\n",
" 'ITEM ANALISADO', 'MATCH_X', 'CRESCIMENTO', 'CICLO', 'INICIO CICLO',\n",
" 'FIM CICLO', 'DURAÇÃO', 'MATCH_Y', 'DIAS_ATE_INICIO',\n",
" 'INICIO CICLO SIMILAR', 'FIM CICLO SIMILAR', 'DURAÇÃO CICLO SIMILAR',\n",
" 'CÓDIGO DO PRODUTO', 'CICLO', 'VENDAS CICLO LANÇAMENTO', 'SKU_Y',\n",
" '202408', '202409', '202410', '202411', '202412', '202413', '202414',\n",
" '202415', '202416', '202417', '202501', '202502', '202503', '202504',\n",
" '202505', '202506', '202507', 'CRESCIMENTO_GERAL',\n",
" 'PICO VENDAS SIMILAR ULTIMOS 6 CICLOS', 'MEDIANA DO HISTÓRICO',\n",
" 'MED_POR_CANAL', 'PDVDEPARA.PRACTICO', 'CÓDIGO', 'CRESCIMENTO_FINAL',\n",
" 'PV GINSENG'],\n",
" dtype='object')"
]
},
"execution_count": 55,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final.columns = df_final.columns.str.upper()\n",
"\n",
"df_final.drop(columns=df_final.filter(regex='HISTÓRICO DE VENDAS DO CICLO').columns, inplace=True)\n",
"\n",
"df_final.columns"
]
},
{
"cell_type": "code",
"execution_count": 56,
"id": "62ce5c62",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(1022, 94)"
]
},
"execution_count": 56,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"df_final.shape"
]
},
{
"cell_type": "code",
"execution_count": 57,
"id": "cecca116",
"metadata": {},
"outputs": [],
"source": [
"df_final[['C-4', 'C-3', 'C-2', 'C-1', 'VENDAS CICLO ATUAL']] = df_final[['C-4', 'C-3', 'C-2', 'C-1', 'VENDAS CICLO ATUAL']].fillna(0)"
]
},
{
"cell_type": "code",
"execution_count": 58,
"id": "733e6e45",
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final[[\n",
" 'SUPERVISOR',\n",
" 'ANALISTA', \n",
" 'CANAL',\n",
" 'UF',\n",
" 'PDV',\n",
" 'DESCRIÇÃO PDV',\n",
" 'PRODUTO LANÇAMENTO',\n",
" 'DESCRIÇÃO DO LANÇAMENTO',\n",
" 'MARCA',\n",
" 'CATEGORIA',\n",
" 'MECANICA CONSUMIDOR',\n",
" '% CONSUMIDOR',\n",
" 'MECANICA REVENDEDOR',\n",
" '% REVENDEDOR',\n",
" 'TIPO DE PRODUTO',\n",
" 'IAF',\n",
" 'FOCO',\n",
" 'PRODUTO SIMILAR',\n",
" 'DESCRIÇÃO SIMILAR',\n",
" 'CICLO SIMILAR',\n",
" 'VENDAS CICLO LANÇAMENTO',\n",
" 'C-4',\n",
" 'C-3',\n",
" 'C-2',\n",
" 'C-1',\n",
" 'VENDAS CICLO ATUAL',\n",
" 'PICO VENDAS SIMILAR ULTIMOS 6 CICLOS',\n",
" 'PV GINSENG'\n",
"]]"
]
},
{
"cell_type": "code",
"execution_count": 59,
"id": "2e3a04cd",
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final[[\n",
" 'SUPERVISOR',\n",
" 'ANALISTA', \n",
" 'CANAL',\n",
" 'UF',\n",
" 'PDV',\n",
" 'DESCRIÇÃO PDV',\n",
" 'PRODUTO LANÇAMENTO',\n",
" 'DESCRIÇÃO DO LANÇAMENTO',\n",
" 'MARCA',\n",
" 'CATEGORIA',\n",
" 'MECANICA CONSUMIDOR',\n",
" '% CONSUMIDOR',\n",
" 'MECANICA REVENDEDOR',\n",
" '% REVENDEDOR',\n",
" 'TIPO DE PRODUTO',\n",
" 'IAF',\n",
" 'FOCO',\n",
" 'PRODUTO SIMILAR',\n",
" 'DESCRIÇÃO SIMILAR',\n",
" 'CICLO SIMILAR',\n",
" 'VENDAS CICLO LANÇAMENTO',\n",
" 'C-4',\n",
" 'C-3',\n",
" 'C-2',\n",
" 'C-1',\n",
" 'VENDAS CICLO ATUAL',\n",
" 'PICO VENDAS SIMILAR ULTIMOS 6 CICLOS',\n",
" 'PV GINSENG'\n",
"]]"
]
},
{
"cell_type": "code",
"execution_count": 60,
"id": "25cbff26",
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final.reindex(columns=[\n",
" 'SUPERVISOR',\n",
" 'ANALISTA',\n",
" 'CANAL',\n",
" 'UF',\n",
" 'PDV',\n",
" 'DESCRIÇÃO PDV',\n",
" 'PRODUTO LANÇAMENTO',\n",
" 'DESCRIÇÃO DO LANÇAMENTO',\n",
" 'MARCA',\n",
" 'CATEGORIA',\n",
" 'MECANICA CONSUMIDOR',\n",
" '% CONSUMIDOR',\n",
" 'MECANICA REVENDEDOR',\n",
" '% REVENDEDOR',\n",
" 'TIPO DE PRODUTO',\n",
" 'IAF',\n",
" 'FOCO',\n",
" 'PRODUTO SIMILAR',\n",
" 'DESCRIÇÃO SIMILAR',\n",
" 'CICLO SIMILAR',\n",
" 'VENDAS CICLO LANÇAMENTO',\n",
" 'C-4',\n",
" 'C-3',\n",
" 'C-2',\n",
" 'C-1',\n",
" 'VENDAS CICLO ATUAL',\n",
" 'PICO VENDAS SIMILAR ULTIMOS 6 CICLOS',\n",
" 'PV GINSENG'])\n"
]
},
{
"cell_type": "code",
"execution_count": 61,
"id": "a3e80cb4",
"metadata": {},
"outputs": [],
"source": [
"df_final['SUGESTÃO METASELLIN'] = ''\n",
"df_final['SUGESTÃO ABASTECIMENTO'] = ''\n",
"df_final['SUGESTÃO COMERCIAL'] = ''\n"
]
},
{
"cell_type": "code",
"execution_count": 62,
"id": "2df3e2e9",
"metadata": {},
"outputs": [],
"source": [
"df_final.to_excel(f'C:/Users/joao.herculano/Documents/Lançamento{hoje}{ciclo_lanc}.xlsx',index=False)"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.13.2"
}
},
"nbformat": 4,
"nbformat_minor": 5
}