Ruptura_Projetada/promoção/promoção_boti_ciclo07.ipynb
João Herculano b2fb8fd8e3 innit 29.05
2025-05-29 09:48:20 -03:00

1225 lines
37 KiB
Plaintext

{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import pandas as pd\n",
"import numpy as np \n",
"import glob\n",
"import os \n",
"\n",
"\n",
"from openpyxl import load_workbook\n",
"from openpyxl.styles import PatternFill, Font"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# O QUE PRECISA PRA RODAR ESSE CÓDIGO:\n",
"\n",
"# Arquivo Draft\n",
"# Arquivo Estoque\n",
"# Arquivo BI preço\n",
"# Arquivo pdv\n",
"# Arquivo Calendario\n",
"# Arquivo tabela de compra\n",
"\n",
"#Atualizar o nome da marca no filtro do estoque."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_tabela = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_PROMOÇÕES\\BOTICARIO\\C10\\TABELA DE PEDIDOS\\Pedidos Semanais Especiais - BOT - 202510.xlsx\")\n",
"\n",
"df_tabela = df_tabela[df_tabela['Ação revendedor'].notna() | df_tabela['Ação consumidor'].notna()]\n",
"\n",
"df_tabela = df_tabela[df_tabela['Região'] == 'NNE'] \n",
"\n",
"df_tabela = df_tabela[(df_tabela['Canal'] != 'Ecomm')]\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['Categoria'] != \"EMBALAGENS\") | (df_tabela['Categoria'] != \"SUPORTE À VENDA\")]\n",
"\n",
"df_tabela = df_tabela[df_tabela['Tipo de pedido'] == 'Semanal']\n",
"\n",
"df_tabela = df_tabela[~df_tabela['Descrição'].str.contains('PRM')]\n",
"\n",
"df_tabela = df_tabela[df_tabela['Tipo de produto']!= 'EDICAO LIMITADA']\n",
"\n",
"df_tabela['Ação revendedor'] = np.where(df_tabela['Ação revendedor'].isna(),df_tabela['Ação consumidor'],df_tabela['Ação revendedor'])\n",
"\n",
"df_tabela['Percentual de desconto revendedor'] = np.where(df_tabela['Percentual de desconto revendedor'].isna(),df_tabela['Percentual de desconto consumidor'],df_tabela['Percentual de desconto revendedor'])\n",
"\n",
"df_tabela['MATCH'] = 1\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_tabela.columns"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_tabela.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_pdv = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_PROMOÇÕES\\BOTICARIO\\C09\\arquivos pra gerar\\pdvs\\PDV_ATT.xlsx\")\n",
"\n",
"df_pdv_origi = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_PROMOÇÕES\\BOTICARIO\\C09\\arquivos pra gerar\\pdvs\\PDV_ATT.xlsx\")\n",
"\n",
"df_pdv = df_pdv.rename(columns={'DESCRIÇÃO':'DESCRIÇÃO PDV'})\n",
"\n",
"df_pdv = df_pdv[df_pdv['STATUS']!=\"INATIVO\"]\n",
"\n",
"df_pdv = df_pdv.drop(columns=['REGIÃO', 'ESTADO','CIDADE','GESTÃO', 'STATUS'])\n",
"\n",
"df_pdv['PDV'] = df_pdv['PDV DESC'].str.split(\"-\").str[0].str.strip()\n",
"\n",
"df_pdv = df_pdv[df_pdv['CANAL']!='MTZ']\n",
"\n",
"#df_pdv['CANAL'] = np.where((df_pdv['CANAL']=='LJ')|(df_pdv['CANAL']=='HIB')|(df_pdv['CANAL']=='CD'),'TODOS','VD')\n",
"\n",
"df_pdv['MATCH'] = 1\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_pdv = df_pdv.drop(columns=['pdv como texto','PDV DESC'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"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\\DB_PROMOÇÕES\\BOTICARIO\\C10\\DRAFT_PDVS_SEM_\" # 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.shape\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_draft = df_draft.drop(columns=['Descrição','Compra inteligente semanal/Sugestão de compra',\n",
" 'Compra inteligente Próximo Ciclo',\n",
" 'Compra inteligente Próximo Ciclo + 1','Planograma', 'Quantidade por caixa', 'Preço Sell In', 'Quantidade',\n",
" 'Item analisado', 'Subcategoria',\n",
" 'Lançamento', 'Desativação',\n",
" 'Promoção Próximo Ciclo', 'Categoria'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"\n",
"\n",
"# Caminho onde estão as subpastas com os arquivos CSV\n",
"pasta_entrada = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_PROMOÇÕES\\BOTICARIO\\C10\\estoque\"\n",
"\n",
"# Lista todas as subpastas dentro de \"ESTOQUE\"\n",
"subpastas = [os.path.join(pasta_entrada, d) for d in os.listdir(pasta_entrada) if os.path.isdir(os.path.join(pasta_entrada, d))]\n",
"\n",
"df_list = []\n",
"\n",
"# Percorre todas as subpastas\n",
"for subpasta in subpastas:\n",
" arquivos = [f for f in os.listdir(subpasta) if f.endswith(\".csv\")]\n",
" nome_pasta = os.path.basename(subpasta) # Obtém o nome da pasta\n",
"\n",
" for arquivo in arquivos:\n",
" caminho_arquivo = os.path.join(subpasta, arquivo)\n",
" try:\n",
" df = pd.read_csv(caminho_arquivo, encoding=\"utf-8\", low_memory=False) # Melhor para grandes volumes de dados\n",
" df[\"Arquivo_Origem\"] = arquivo # Adiciona o nome do arquivo de origem\n",
" df[\"Pasta_Origem\"] = nome_pasta # Adiciona o nome da pasta de origem\n",
" df_list.append(df)\n",
" except Exception as e:\n",
" print(f\"Erro ao ler o arquivo {arquivo}: {e}\")\n",
"\n",
"if df_list:\n",
" df_estoque = pd.concat(df_list, ignore_index=True)\n",
"\n",
"df_estoque['PDV'] = df_estoque['PDV'].astype(str)\n",
"\n",
"df_estoque['SKU_FINAL'] = np.where(df_estoque['SKU_PARA'] == \"-\", df_estoque['SKU'], df_estoque['SKU_PARA'])\n",
"\n",
"df_estoque['SKU_FINAL']=df_estoque['SKU_FINAL'].astype(str)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_tabela.columns"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_tabela = pd.merge(left=df_tabela,right=df_estoque[['SKU','SKU_FINAL']],left_on='Código',right_on='SKU',how='inner')\n",
"\n",
"df_tabela['Código'] = df_tabela['SKU_FINAL']\n",
"\n",
"df_tabela = df_tabela.drop(columns=['SKU','SKU_FINAL'])\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_estoque = df_estoque.drop(columns=['DESCRICAO', 'CATEGORIA', 'CLASSE', 'FASES PRODUTO',\n",
" 'LANCAMENTO', 'DESATIVACAO','COBERTURA ALVO',\n",
" 'ESTOQUE DE SEGURANCA','COBERTURA PROJETADA', \n",
" 'Pasta_Origem'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_estoque"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_bi_preco = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_PROMOÇÕES\\BOTICARIO\\C09\\arquivos pra gerar\\preços bi\\TABELA DE PREÇOS (4).xlsx\")\n",
"\n",
"df_bi_preco = df_bi_preco.drop(columns=['Descrição','Tipo Preço','CATEGORIA','LINHA','MARCA'])\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final = pd.merge(left=df_tabela,right=df_pdv,on='MATCH',how='inner')\n",
"\n",
"df_final = df_final.drop_duplicates()\n",
"\n",
"df_final.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['PDV'] = df_final['PDV'].astype('Int64')\n",
"df_final['Código'] = df_final['Código'].astype('Int64')\n",
"\n",
"\n",
"df_final = pd.merge(left=df_final,right=df_draft,left_on=['PDV','Código'],right_on=['PDV','SKU'],how='left')\n",
"df_final.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final[(df_final['Código'] == 52023) & (df_final['PDV'] == 23712)]['Histórico de Vendas do Ciclo 202505']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final.drop(columns=['Sortimento P', 'Sortimento M',\n",
" 'Sortimento G','MARCA','SKU'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"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"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#ignorando a PDV que ainda não está online\n",
"df_pdv = df_pdv[df_pdv['DESCRIÇÃO PDV'] != '23813-COMERCIO-HIB VALENTE']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"**ALTERAR NOME DA COLUNA \"ARQUIVO_ORIGEM\" PARA UMA DAS OPÇÕES ABAIXO:**\n",
"\n",
"*BOT.csv* \n",
"\n",
"*EUD.csv*\n",
"\n",
"*QDB.csv*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"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",
"calendario['ANO_CICLO'] = calendario['Ciclo'].str[0:5]\n",
"\n",
"\n",
"calendario = calendario[calendario['MARCA'] == \"BOTICARIO\"]\n",
"\n",
"calendario = calendario.drop(columns='MARCA')\n",
"\n",
"calendario['CICLOMAIS2'] = calendario['ANO_CICLO'].astype(str) + (calendario['NUM_CICLO'].astype(int) + 2).astype(str).str.zfill(2) # >>>>>>>>> MUDAR PRA CICLO CORRETO \n",
"\n",
"ciclo_mais2 = calendario[calendario['Date'].dt.normalize() == today]['CICLOMAIS2'].iloc[0]\n",
"\n",
"\n",
"# Filter rows where date matches today\n",
"filtered_calendario = calendario[calendario['Ciclo'] == ciclo_mais2][:1]\n",
"\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\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"filtered_calendario['MATCH'] = 1"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_pdv['UF'] = np.where(df_pdv['UF'] == 'VDC','BA',df_pdv['UF'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#df_tabela = df_tabela[(df_tabela['Tipo de promoção'] == \"Revendedor\" ) | (df_tabela['Tipo de promoção'] == \"Promoções\") |(df_tabela['Tipo de promoção'] == \"Promoções | Revendedor\" )]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_draft['PDV'] = df_draft['PDV'].astype(str)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final = pd.merge(left=df_final, right=filtered_calendario[['Ciclo','INICIO CICLO','FIM CICLO','DURAÇÃO','MATCH','dias_ate_inicio']], on='MATCH',how='inner')\n",
"df_final.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['Código'] = df_final['Código'].astype('Int64') \n",
"df_final['PDV'] = df_final['PDV'].astype('Int64') \n",
"\n",
"df_estoque['PDV'] = df_estoque['PDV'].astype('Int64') \n",
"df_estoque['SKU_FINAL'] = df_estoque['SKU_FINAL'].astype('Int64') \n",
"\n",
"df_final = pd.merge(left=df_final,right=df_estoque,right_on=['PDV','SKU_FINAL'],left_on=['PDV','Código'],how='left')\n",
"df_final.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['Código'] = df_final['Código'].astype('str')\n",
"\n",
"df_bi_preco['SKU2'] = df_bi_preco['SKU2'].astype('str')\n",
"\n",
"df_final = pd.merge(left=df_final,right=df_bi_preco,right_on=['UF','SKU2'],left_on=['UF','Código'],how='left')\n",
"df_final.shape "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_bi_preco['SKU1'] = df_bi_preco['SKU1'].astype(str).str.replace('.0','',regex=False) \n",
"\n",
"df_final = pd.merge(left=df_final,right=df_bi_preco[['SKU1', 'SKU2', 'UF', 'PC', 'PV']],right_on=['UF','SKU1'],left_on=['UF','Código'],how='left')\n",
"df_final.shape "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['PRECO DE COMPRA'] = np.where(~df_final['PC_x'].isna(),df_final['PC_x'],df_final['PC_y'])\n",
"\n",
"df_final['PRECO DE VENDA'] = np.where(~df_final['PV_x'].isna(),df_final['PV_x'],df_final['PV_y'])\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['CANAL'] = np.where((df_final['CANAL'] == 'LJ') | (df_final['CANAL'] == 'HIB'), \"TODOS\" , np.where((df_final['CANAL'] == 'CD') | (df_final['CANAL'] == 'VD'), \"VD\", df_final['CANAL']))\n",
"\n",
"df_final['CANAL'].value_counts()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_estoque = df_estoque.rename(columns={'SKU_FINAL':'SKU_PARA_VALIDACAO'})\n",
"\n",
"df_estoque['SKU_PARA_VALIDACAO'] = df_estoque['SKU_PARA_VALIDACAO'].astype('Int64')\n",
"\n",
"df_final = pd.merge( left= df_final, right = df_estoque[['SKU_PARA_VALIDACAO','Arquivo_Origem']], left_on= 'SKU', right_on='SKU_PARA_VALIDACAO', how='left')\n",
"\n",
"df_final = df_final.drop_duplicates()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final.drop(columns=['SKU1_x','SKU1_y','SKU2_x','SKU2_y','PC_x', 'PV_x','PC_y', 'PV_y','Subcategoria',\n",
"'Carteira Bloqueada Para Novos Pedidos',\n",
"'Quantidade por caixa'\n",
"])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['UFPRODUTO'] = df_final['UF'].astype(str) + df_final['SKU'].astype(str)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['Projeção Próximo Ciclo + 1'] =df_final['Projeção Próximo Ciclo + 1'] - df_final['Projeção Próximo Ciclo'] # projeção do ciclo em estudo"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['Data Prevista Regularização'] = df_final['Data Prevista Regularização'].astype(str).replace('0','REGULAR')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final.rename(columns={'Compra inteligente Próximo Ciclo + 1':'Compra inteligente Próximo Ciclo','Arquivo_Origem': 'MARCA'})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final[~df_final['Marca'].isna()]\n",
"df_final['Marca'].isna().sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final.drop_duplicates()\n",
"df_final.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final[df_final.columns[26:43]] = df_final[df_final.columns[26:43]].fillna(0)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final.columns[26:44]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Define list of target columns\n",
"sales_2024_cols = df_final.columns[26:44]\n",
"# Create a new column with the row-wise max\n",
"df_final['PICO DE VENDAS 2024'] = df_final[sales_2024_cols].max(axis=1)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final.columns[37:44]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"vendas_6_meses = df_final.columns[37:44]\n",
"\n",
"df_final['Pico Vendas Ultimos 6 ciclos'] = df_final[vendas_6_meses].max(axis=1)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final.columns[37:44]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Define as colunas mensais\n",
"colunas_mensais = df_final.columns[26:43]\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_final.groupby('PDV').apply(calcular_crescimento)\n",
"\n",
"# Merge do resultado de volta no dataframe original\n",
"df_final = df_final.merge(crescimento_por_pdv, on='PDV', how='left')\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Suponha que os meses estão nas colunas 10 a 26 (17 colunas = 17 meses)\n",
"colunas_mensais = df_final.columns[26:43]\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": null,
"metadata": {},
"outputs": [],
"source": [
"vendas_todos_historicos = df_final.columns[26:44]\n",
"\n",
"df_final['MEDIANA DO HISTÓRICO'] = df_final[vendas_todos_historicos].median(axis=1)\n",
"\n",
"df_final['MEDIA DO HISTÓRICO'] = df_final[vendas_todos_historicos].mean(axis=1)\n",
"\n",
"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",
"\n",
"df_final = pd.merge(left=df_final, right=medi,on='CANAL',how='inner')\n",
"\n",
"medi"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final.columns[28:29].str.split(\" \")[0][-1]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"mesmo_ciclo_ano_passado = df_final.columns[28:29]\n",
"ciclo_ano_passado = df_final.columns[28:29].str.split(\" \")[0][-1]\n",
"df_final[ciclo_ano_passado] = df_final[mesmo_ciclo_ano_passado]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final['CRESCIMENTO_FINAL'] = df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO'] #crescimento do pdv\n",
"\n",
"df_final['CRESCIMENTO_FINAL'] = np.where(df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO']>0.8,0.8,df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO'])\n",
"\n",
"df_final['CRESCIMENTO_FINAL'] = np.where(df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO']<0,0,df_final['CRESCIMENTO_GERAL'] + df_final['CRESCIMENTO'])\n",
"\n",
"df_final['MEDIANA DO HISTÓRICO'] = np.where(df_final['MEDIANA DO HISTÓRICO']==0,df_final['MEDIA DO HISTÓRICO'] ,df_final['MEDIANA DO HISTÓRICO'])\n",
"\n",
"# Primeiro cálculo intermediário\n",
"df_final['PV GINSENG'] = np.where(df_final['CRESCIMENTO_FINAL'] * df_final[ciclo_ano_passado] + df_final[ciclo_ano_passado] <1,\n",
" round(df_final['CRESCIMENTO_FINAL'] * df_final['MEDIANA DO HISTÓRICO']+ df_final['MEDIANA DO HISTÓRICO'],0), \n",
" round(df_final['CRESCIMENTO_FINAL']*df_final[ciclo_ano_passado]+df_final[ciclo_ano_passado],0))\n",
"\n",
"\n",
"df_final.shape"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final.columns[26:39]"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final = df_final.rename(columns={df_final.columns[39]: \"C-4\", df_final.columns[40]: \"C-3\",df_final.columns[41]: \"C-2\",df_final.columns[42]: \"C-1\"})"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final.drop(columns=df_final.columns[26:39], inplace=True)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# List all columns except the two\n",
"cols_to_group_by = df_final.columns.difference(['DDV PREVISTO', 'COBERTURA ATUAL'])\n",
"\n",
"# Group and aggregate\n",
"df_final_dedup = (\n",
" df_final\n",
" .groupby(list(cols_to_group_by), dropna=False)[['DDV PREVISTO', 'COBERTURA ATUAL']]\n",
" .max()\n",
" .reset_index()\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['DDV PREVISTO'] = df_final_dedup['DDV PREVISTO'].fillna(0.01)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup[(df_final['PDV'] == 23712)]['C-3']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['DDV PREVISTO'] = np.where(\n",
" df_final_dedup['DDV PREVISTO'] == 0,\n",
" 0.01,\n",
" df_final_dedup['DDV PREVISTO']\n",
")\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup.columns"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['EST PROJE FINAL CICLO ATUAL'] = (df_final_dedup['Estoque Atual'] + df_final_dedup['Estoque em Transito']) - round(df_final_dedup['dias_ate_inicio'] * df_final_dedup['DDV PREVISTO'],0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['EST PROJE FINAL CICLO ATUAL'] = np.where(df_final_dedup['EST PROJE FINAL CICLO ATUAL']<0,0,df_final_dedup['EST PROJE FINAL CICLO ATUAL'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['VENDAS R$ PV GINSENG'] = df_final_dedup['PRECO DE VENDA'] * df_final_dedup['PV GINSENG']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_estoque.columns"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Columns to bring up front\n",
"priority_cols = [\n",
" 'SKU',\t'Marca',\t'INICIO CICLO',\n",
" 'FIM CICLO',\t'DURAÇÃO',\t'PRECO DE COMPRA',\t'PRECO DE VENDA',\n",
" 'UFPRODUTO',\t'Item Desativado',\t'Data Prevista Regularização',\n",
" 'ANALISTA',\t'UF',\t'CANAL',\t'PDV',\t'DESCRIÇÃO PDV',\t'Classe',\n",
" 'Descrição',\t'Categoria',\n",
"\t'ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO',\t'COBERTURA ATUAL',\n",
" 'Pedido Pendente',\t'PICO DE VENDAS 2024','Pico Vendas Ultimos 6 ciclos',\n",
" 'C-4',\t'C-3',\t'C-2',\t'C-1',\t'Histórico de Vendas do Ciclo Atual',\n",
" 'Dias sem venda'\n",
"]\n",
"\n",
"# All remaining columns\n",
"other_cols = [col for col in df_final_dedup.columns if col not in priority_cols]\n",
"\n",
"# Reorder\n",
"'Ação consumidor', 'Percentual de desconto consumidor', 'Ação revendedor', 'Percentual de desconto revendedor', '202408'\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#df_final_dedup = df_final_dedup[priority_cols + other_cols]\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['RBV 202406'] = df_final_dedup['PRECO DE VENDA'] * df_final_dedup[ciclo_ano_passado] "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['COB PROJETADA'] = np.where(\n",
" df_final_dedup['DDV PREVISTO'] != 0,\n",
" (df_final_dedup['EST PROJE FINAL CICLO ATUAL'] + df_final_dedup['PV GINSENG']) / df_final_dedup['DDV PREVISTO'],\n",
" 999)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup.drop(df_final_dedup.columns[39:40], axis=1, inplace=True)\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup.drop(columns=['dias_ate_inicio','SKU_FINAL',\n",
" 'CRESCIMENTO'],inplace=True)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#df_final_dedup['MARCA'] = df_final_dedup['MARCA'].str.replace('.csv','',regex=False)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['COB PROJETADA'] = df_final_dedup['COB PROJETADA'].fillna(999)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"marca_promo = df_estoque['Arquivo_Origem'].iloc[0].replace('.csv','')\n",
"marca_promo"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['INICIO CICLO'] = pd.to_datetime(df_final_dedup['INICIO CICLO'], dayfirst=True).dt.strftime('%d/%m/%Y')\n",
"\n",
"df_final_dedup['FIM CICLO'] = pd.to_datetime(df_final_dedup['FIM CICLO'], dayfirst=True).dt.strftime('%d/%m/%Y')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['Percentual de desconto revendedor'] = np.where((df_final_dedup['Percentual de desconto revendedor'].isna()) & (~df_final_dedup['Percentual de desconto consumidor'].isna()),df_final_dedup['Percentual de desconto consumidor'],df_final_dedup['Percentual de desconto revendedor'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_pdv_origi['PDV'] = df_pdv_origi['PDV'].astype('Int64')\n",
"df_final_dedup['PDV'] = df_final_dedup['PDV'].astype('Int64')\n",
"\n",
"\n",
"df_final_dedup = pd.merge(left=df_final_dedup,right=df_pdv_origi[['PDV','CANAL','UF']],how='inner',on='PDV')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_vdc = pd.read_csv(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\DB_PROMOÇÕES\\BOTICARIO\\C10\\VENDA VITORIA 2024\\VENDA VITORIA.csv\")\n",
"\n",
"df_vdc['PRODUTO'] = df_vdc['PRODUTO'].astype('Int64')\n",
"\n",
"df_final_dedup['Código'] = df_final_dedup['Código'].astype('Int64')\n",
"\n",
"df_final_dedup =pd.merge(left=df_final_dedup,right=df_vdc[['PDV GINSENG','PRODUTO',ciclo_ano_passado]],left_on= ['PDV','Código'],right_on= ['PDV GINSENG','PRODUTO'],how='left' )\n",
"\n",
"df_final_dedup['202410_y'] = df_final_dedup['202410_y'].fillna(0)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup.head()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['202410_x'] = np.where(df_final_dedup['202410_y']>0,df_final_dedup['202410_y'],df_final_dedup['202410_x'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup = df_final_dedup.drop(columns=['Arquivo_Origem_x','Arquivo_Origem_y','CANAL_x','Canal',\n",
" 'Ciclo_x','Ciclo_y','DURAÇÃO','FIM CICLO','Foco','INICIO CICLO','MATCH',\n",
" 'PRECO DE COMPRA','SKU','SKU_PARA','SKU_PARA_VALIDACAO',\n",
" 'Tipo de pedido',\t'Tipo de produto','UFPRODUTO','Unidade de negócio','EST PROJE FINAL CICLO ATUAL',\n",
" 'UF_x','RBV 202406','Região','Catálogo','SKU','VENDAS R$ PV GINSENG','Data Prevista Regularização',\n",
" 'IAF', 'Item Desativado','Tipo de promoção','PDV GINSENG','PRODUTO','202410_y',\n",
" 'ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO','COBERTURA ATUAL + TRANSITO',\n",
" 'DDV PREVISTO',\t'COB PROJETADA','COBERTURA ATUAL',\n",
" 'CRESCIMENTO_FINAL',\t'CRESCIMENTO_GERAL','med_por_canal','PEDIDO PENDENTE'])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup = df_final_dedup.rename(columns={'CANAL_y':'CANAL','UF_y':'UF','Marca':'LINHA','202410_x':'202410'})\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup.columns"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup[(df_final['PDV'] == 23712)]['C-3']"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"priority_cols = ['SUPERVISOR','ANALISTA','UF','CANAL','LINHA','PDV','DESCRIÇÃO PDV','Código','Descrição','Categoria', \n",
"'Classe','Percentual de desconto consumidor','Ação consumidor','Percentual de desconto revendedor','Ação revendedor','C-1',\n",
"'C-2', 'C-3', 'C-4','Histórico de Vendas do Ciclo Atual','Estoque Atual','Estoque em Transito','Pedido Pendente',\n",
"'Projeção Próximo Ciclo + 1','Projeção Próximo Ciclo']\n",
"\n",
"# All remaining columns\n",
"other_cols = [col for col in df_final_dedup.columns if col not in priority_cols]\n",
"\n",
"# Reorder\n",
"df_final_dedup = df_final_dedup[priority_cols + other_cols]\n",
"\n",
"df_final_dedup['SUGESTÃO ABASTECIMENTO'] = ''\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup = df_final_dedup.drop_duplicates()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup['PV GINSENG'].sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"df_final_dedup[df_final_dedup['PDV'] == 23712]['PICO DE VENDAS 2024'].isna().sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# Export to Excel\n",
"output_file = f'C:\\\\Users\\\\joao.herculano\\\\Documents\\\\promoção_{marca_promo}_{ciclo_mais2}28.05.xlsx'\n",
"with pd.ExcelWriter(output_file, engine='openpyxl') as writer:\n",
" df_final_dedup.to_excel(writer, index=False)\n",
"\n",
"# Apply styles\n",
"wb = load_workbook(output_file)\n",
"ws = wb['Sheet1']\n",
"\n",
"# Style header\n",
"header_fill = PatternFill(start_color='ADD8E6', end_color='ADD8E6', fill_type='solid') # Light Blue\n",
"header_font = Font(color='FFFFFF', bold=True) # White & Bold\n",
"\n",
"for cell in ws[1]:\n",
" cell.fill = header_fill\n",
" cell.font = header_font\n",
"\n",
"# Style rows: gray/white alternating\n",
"gray_fill = PatternFill(start_color='DDDDDD', end_color='DDDDDD', fill_type='solid') # Light gray\n",
"\n",
"for i, row in enumerate(ws.iter_rows(min_row=2, max_row=ws.max_row), start=2):\n",
" if i % 2 == 0:\n",
" for cell in row:\n",
" cell.fill = gray_fill\n",
"\n",
"# Save styled workbook\n",
"wb.save(output_file)\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"coisas q saem\n",
"\n",
"Lançamento\n",
"Subcategoria\n",
"Projeção Próximo Ciclo \n",
"Promoção Próximo Ciclo\n",
"Compra inteligente semanal/Sugestão de compra\n",
"Compra inteligente Próximo Ciclo\n",
"Planograma\n",
"Carteira Bloqueada Para Novos Pedidos\n",
"Quantidade por caixa\n",
"Preço Sell In\n",
"Quantidade\n",
"Item analisado\n",
"Tipo Preço\n",
"\n",
">>>>>>>>>>>>>NAO ESTÁ PEGANDO O MERGE COM O DF_ESTOQUE\n",
"\n",
"\n",
"CRIAR PROJEÇÃO DE VENDA DO CICLO ATUAL\n",
"Compra inteligente Próximo Ciclo + 1 >>>>>>> RENAME PRA NOROMAL"
]
}
],
"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": 2
}