{ "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", "\n", "from datetime import datetime\n", "from openpyxl import load_workbook\n", "from openpyxl.styles import PatternFill, Font" ] }, { "cell_type": "code", "execution_count": 2, "id": "fa16d50c", "metadata": {}, "outputs": [], "source": [ "hoje = datetime.today().strftime('%Y-%m-%d')" ] }, { "cell_type": "code", "execution_count": 9, "id": "9fcdc77a", "metadata": {}, "outputs": [], "source": [ "calendario = pd.read_excel(r\"..\\\\..\\\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\arquivos usados por todos os lançamentos\\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) + 2).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": 11, "id": "bbec229d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CicloINICIO CICLOFIM CICLODURAÇÃOMARCADateNUM_CICLOANO_CICLOCICLOMAIS2dias_ate_iniciomatch
2507C2025172025-12-012025-12-2525BOTICARIO2025-12-0117C2025C202519451
\n", "
" ], "text/plain": [ " Ciclo INICIO CICLO FIM CICLO DURAÇÃO MARCA Date \\\n", "2507 C202517 2025-12-01 2025-12-25 25 BOTICARIO 2025-12-01 \n", "\n", " NUM_CICLO ANO_CICLO CICLOMAIS2 dias_ate_inicio match \n", "2507 17 C2025 C202519 45 1 " ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "filtered_calendario" ] }, { "cell_type": "code", "execution_count": 12, "id": "0245ed28", "metadata": {}, "outputs": [], "source": [ "ciclo_lanc = filtered_calendario['Ciclo'].max()" ] }, { "cell_type": "code", "execution_count": 13, "id": "7a3c1e6f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'C202517'" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ciclo_lanc" ] }, { "cell_type": "code", "execution_count": 15, "id": "61ffc777", "metadata": {}, "outputs": [], "source": [ "#COLOCAR ARQUIVO SIMILAR AQUI (ALTERAR)\n", "\n", "arquivo_similares = r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C17\\arquivos para geração da sugestão\\similar novo splash\\PRODUTOS SIMILARES - BOT(body splash).xlsx\"\n", "\n", "df_similares = pd.read_excel(arquivo_similares)\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', 'FIM DO CICLO', 'DURAÇÃO CICLO','INICIO CICLO SIMILAR','FIM CICLO SIMILAR','DURAÇÃO CICLO SIMILAR'])" ] }, { "cell_type": "code", "execution_count": 16, "id": "7eaf9237", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PRODUTO LANÇAMENTODESCRIÇÃO DO LANÇAMENTOPRODUTO SIMILARDESCRIÇÃO SIMILARCICLO SIMILARFOCOIAFCATEGORIAMARCA% CONSUMIDORMECANICA CONSUMIDOR% REVENDEDORMECANICA REVENDEDORTIPO DE PRODUTOMATCH
086116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM----REGULAR1
\n", "
" ], "text/plain": [ " PRODUTO LANÇAMENTO DESCRIÇÃO DO LANÇAMENTO \\\n", "0 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "\n", " PRODUTO SIMILAR DESCRIÇÃO SIMILAR \\\n", "0 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "\n", " CICLO SIMILAR FOCO IAF CATEGORIA MARCA % CONSUMIDOR \\\n", "0 C202506 Não Não PERFUMARIA CUIDE-SE BEM - \n", "\n", " MECANICA CONSUMIDOR % REVENDEDOR MECANICA REVENDEDOR TIPO DE PRODUTO MATCH \n", "0 - - - REGULAR 1 " ] }, "execution_count": 16, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_similares.head()" ] }, { "cell_type": "code", "execution_count": 17, "id": "ad836441", "metadata": {}, "outputs": [], "source": [ "#TRANSFORMA A COLUNA EM STRING\n", "df_similares['PRODUTO SIMILAR'] = df_similares['PRODUTO SIMILAR'].astype('str')\n", "# TIRA O '.0' DO FIM SE OCORRER\n", "df_similares['PRODUTO SIMILAR'] = df_similares['PRODUTO SIMILAR'].replace(r'\\.0$', '', regex=True)\n", "\n", "\n" ] }, { "cell_type": "code", "execution_count": 19, "id": "fe922f62", "metadata": {}, "outputs": [], "source": [ "# SEMPRE COLOCAR O DO USUARIO.(ALTERAR)\n", "df_tabela = pd.read_excel(r\"C:\\Users\\joao.herculano\\GRUPO GINSENG\\Assistência Suprimentos - 2025\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C17\\arquivos para geração da sugestão\\TABELA DE PEDIDO\\Pedidos Semanais Especiais - BOT - 202517.xlsx\")\n", "\n", "# FILTRA REGIÃO = NORDESTE\n", "df_tabela = df_tabela[df_tabela['Região'] == 'NNE'] \n", "# TIRA CANAL ECOMERCE DO PLANILHA\n", "df_tabela = df_tabela[(df_tabela['Canal'] != 'Ecomm') | (df_tabela['Canal'] != 'Ecomm | VD') | (df_tabela['Canal'] != 'Ecomm | Loja')] \n", "# UNIFICA DESCONTOS CANAL LOJA\n", "df_tabela['Canal'] = np.where((df_tabela['Canal'] == \"Loja\") | (df_tabela['Canal'] == \"Todos\") | (df_tabela['Canal'] == \"Loja | VD\"),\"TODOS\",\"VD\")\n", "# SÓ MANTÉM LANÇAMENTOS \n", "df_tabela = df_tabela[df_tabela['Tipo de promoção'].str.contains('Lançamentos', na=False)]" ] }, { "cell_type": "code", "execution_count": 20, "id": "e0c55962", "metadata": {}, "outputs": [], "source": [ "df_pdv = pd.read_excel(r\"..\\\\..\\\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C16\\arquivos para geração da sugestão\\PDV\\PDV_ATT.xlsx\")\n", "# remove lojas QDB\n", "df_pdv = df_pdv[~df_pdv['PDV'].isin([910173, 910291])]\n", "\n", "#feito para retificar os UFS ao fim do script\n", "df_pdv_origi = pd.read_excel(r\"..\\\\..\\\\SUPRIMENTOS\\BD_LANÇAMENTOS\\BOT\\BOT - C16\\arquivos para geração da sugestão\\PDV\\PDV_ATT.xlsx\")\n", "df_pdv_origi = df_pdv_origi[~df_pdv_origi['PDV'].isin([910173, 910291])]" ] }, { "cell_type": "code", "execution_count": 21, "id": "a7b41ecb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVCANALDESCRIÇÃOPDV DESCREGIÃOESTADOCIDADEUFMARCAANALISTAGESTÃOSUPERVISORSTATUSANALISTA EUD
023156LJSHOPPING CENTRO SULNaNNaNSERGIPENaNSENaNInativaInativaInativaINATIVOLOJA
14494MTZESCRITORIO4494-COMERCIO-PONTA VERDE-MACEIONDALAGOASMACEIÓALCP GINSENGInativaInativaInativaINATIVOINATIVO
21137MTZAMG1137-AMG SERRARIANDALAGOASMACEIÓALO BOTICARIOInativaInativaInativaINATIVOINATIVO
312522LJMACEIO SHOP EXP12522-COMERCIO -MACEIO SHOP EXPANSAOMCZ BAIXAALAGOASMACEIÓALO BOTICARIOLUANBetina MeloEfigênia HerculanoATIVOLOJA
412817LJSHOPPING PATIO12817-COMERCIO -SHOPPING PATIOMCZ ALTAALAGOASMACEIÓALO BOTICARIOJEFFERSONPamella BarbosaMaxwell VieiraATIVOLOJA
.............................................
7924257HIBMiguel CalmonNaNNaNNaNNaNBA3O BOTICARIOTHAYLLANCaio LunaFERNANDAATIVOHARY
8024268LJCOMERCIO-LJ JACOBINANaNNaNNaNNaNBA3O BOTICARIOTHAYLLANCaio LunaFERNANDAATIVOLOJA
8124269VDCOMERCIO-ER JACOBINANaNNaNNaNNaNBA3O BOTICARIOJEFFERSONCaio LunaFERNANDAATIVOHARY
8224293HIBCOMERCIO-HIB MORRO DO CHAPEUNaNNaNNaNNaNBA3O BOTICARIOMARCYARAAlyssonFERNANDAATIVODIELLY
8523813HIBVALENTENaNNaNNaNNaNBAO BOTICARIOMARCYARANaNCLÁUDIAATIVOHARY
\n", "

84 rows × 14 columns

\n", "
" ], "text/plain": [ " PDV CANAL DESCRIÇÃO \\\n", "0 23156 LJ SHOPPING CENTRO SUL \n", "1 4494 MTZ ESCRITORIO \n", "2 1137 MTZ AMG \n", "3 12522 LJ MACEIO SHOP EXP \n", "4 12817 LJ SHOPPING PATIO \n", ".. ... ... ... \n", "79 24257 HIB Miguel Calmon \n", "80 24268 LJ COMERCIO-LJ JACOBINA \n", "81 24269 VD COMERCIO-ER JACOBINA \n", "82 24293 HIB COMERCIO-HIB MORRO DO CHAPEU \n", "85 23813 HIB VALENTE \n", "\n", " PDV DESC REGIÃO ESTADO CIDADE UF \\\n", "0 NaN NaN SERGIPE NaN SE \n", "1 4494-COMERCIO-PONTA VERDE-MACEIO ND ALAGOAS MACEIÓ AL \n", "2 1137-AMG SERRARIA ND ALAGOAS MACEIÓ AL \n", "3 12522-COMERCIO -MACEIO SHOP EXPANSAO MCZ BAIXA ALAGOAS MACEIÓ AL \n", "4 12817-COMERCIO -SHOPPING PATIO MCZ ALTA ALAGOAS MACEIÓ AL \n", ".. ... ... ... ... ... \n", "79 NaN NaN NaN NaN BA3 \n", "80 NaN NaN NaN NaN BA3 \n", "81 NaN NaN NaN NaN BA3 \n", "82 NaN NaN NaN NaN BA3 \n", "85 NaN NaN NaN NaN BA \n", "\n", " MARCA ANALISTA GESTÃO SUPERVISOR STATUS \\\n", "0 NaN Inativa Inativa Inativa INATIVO \n", "1 CP GINSENG Inativa Inativa Inativa INATIVO \n", "2 O BOTICARIO Inativa Inativa Inativa INATIVO \n", "3 O BOTICARIO LUAN Betina Melo Efigênia Herculano ATIVO \n", "4 O BOTICARIO JEFFERSON Pamella Barbosa Maxwell Vieira ATIVO \n", ".. ... ... ... ... ... \n", "79 O BOTICARIO THAYLLAN Caio Luna FERNANDA ATIVO \n", "80 O BOTICARIO THAYLLAN Caio Luna FERNANDA ATIVO \n", "81 O BOTICARIO JEFFERSON Caio Luna FERNANDA ATIVO \n", "82 O BOTICARIO MARCYARA Alysson FERNANDA ATIVO \n", "85 O BOTICARIO MARCYARA NaN CLÁUDIA ATIVO \n", "\n", " ANALISTA EUD \n", "0 LOJA \n", "1 INATIVO \n", "2 INATIVO \n", "3 LOJA \n", "4 LOJA \n", ".. ... \n", "79 HARY \n", "80 LOJA \n", "81 HARY \n", "82 DIELLY \n", "85 HARY \n", "\n", "[84 rows x 14 columns]" ] }, "execution_count": 21, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_pdv" ] }, { "cell_type": "code", "execution_count": 22, "id": "a3a045d9", "metadata": {}, "outputs": [], "source": [ "\n", "#trativa de dados\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') | (df_pdv['UF'] == 'BA3'),'BA',df_pdv['UF'])\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": 23, "id": "df04a501", "metadata": {}, "outputs": [], "source": [ "# DISTRIBUINDO OS PDVS PARA OS SIMILARES\n", "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": 24, "id": "f229ed0f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PRODUTO LANÇAMENTO\n", "86116 76\n", "Name: count, dtype: int64" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#CHECAGEM DE QTD PDVS POR PRODUTO LANÇAMENTO.\n", "df_similares['PRODUTO LANÇAMENTO'].value_counts()" ] }, { "cell_type": "code", "execution_count": 25, "id": "0da911af", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\3630339320.py:39: UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.\n", " dfi = pd.read_sql_query(query, conn)\n" ] } ], "source": [ "import pyodbc\n", "import configparser\n", "\n", "#query de vendas por ciclo\n", "\n", "config = configparser.ConfigParser()\n", "config.read(r\"../../SUPRIMENTOS/BD_LANÇAMENTOS/BOT/arquivos usados por todos os lançamentos/credenciais.ini\")\n", "\n", "conn = pyodbc.connect(\n", " f\"DRIVER={{SQL Server}};\"\n", " f\"SERVER={config['banco']['host']},1433;\"\n", " f\"DATABASE=GINSENG;\"\n", " f\"UID={config['banco']['user']};\"\n", " f\"PWD={config['banco']['password']}\"\n", ")\n", "\n", "query = f'''\n", "SELECT \n", " B.PDV, \n", " B.SKU,\n", " bd.SKU2, \n", " COALESCE(bd.SKU2, b.SKU) AS SKU_FINAL,\n", " B.DESCRICAO,\n", " SUM(CAST(b.VENDAS AS DECIMAL(18,2))) AS VENDAS_CICLO,\n", " C.Ciclo\n", "FROM base_vendas_bi b\n", "INNER JOIN ciclos_data_2025 c \n", " ON CAST(b.[DATA] AS DATE) = CONVERT(DATE, c.[Date], 103) AND C.MARCA = 'BOT'\n", "LEFT JOIN base_depara bd on b.SKU = bd.SKU \n", "WHERE CAST(b.[DATA] AS DATE) >= DATEADD(YEAR, -1, GETDATE())\n", "GROUP BY\n", " B.PDV, \n", " B.SKU,\n", " bd.SKU2,\n", " B.DESCRICAO,\n", " C.Ciclo\n", "HAVING SUM(CAST(b.VENDAS AS DECIMAL(18,2))) > 0\n", "'''\n", "dfi = pd.read_sql_query(query, conn)\n", "conn.close()\n", "\n", "dfi['SKU2'] = dfi['SKU2'].fillna(\"-\")\n" ] }, { "cell_type": "code", "execution_count": 26, "id": "20634105", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKU_FINALDESCRICAOC202415C202416C202417C202501C202502C202503C202504...C202506C202507C202508C202509C202510C202511C202512C202513C202514C202515
0125221080INTENSE GLOS LAB BUBBAL TUT/FRUT 5ml0.010.02.02.01.02.03.0...7.017.00.00.00.00.00.00.00.00.0
1125221296PMPCK THE BLEND DES ANTIT AER 2x75g3.02.00.00.00.00.00.0...0.00.00.00.00.00.00.02.01.00.0
2125221302PMPCK LILY DES ANTIT AER 2x75g5.06.00.00.00.00.00.0...3.04.00.04.04.02.01.06.00.00.0
3125221314PMPCK ZAAD DES ANTIT AER 2x75g1.01.00.00.00.00.00.0...0.00.00.00.00.01.01.01.00.00.0
4125221317PMPCK MALBEC DES ANTIT AER 2x75g2.05.00.01.03.00.00.0...1.01.00.02.02.03.02.05.00.00.0
\n", "

5 rows × 21 columns

\n", "
" ], "text/plain": [ " PDV SKU_FINAL DESCRICAO C202415 C202416 \\\n", "0 12522 1080 INTENSE GLOS LAB BUBBAL TUT/FRUT 5ml 0.0 10.0 \n", "1 12522 1296 PMPCK THE BLEND DES ANTIT AER 2x75g 3.0 2.0 \n", "2 12522 1302 PMPCK LILY DES ANTIT AER 2x75g 5.0 6.0 \n", "3 12522 1314 PMPCK ZAAD DES ANTIT AER 2x75g 1.0 1.0 \n", "4 12522 1317 PMPCK MALBEC DES ANTIT AER 2x75g 2.0 5.0 \n", "\n", " C202417 C202501 C202502 C202503 C202504 ... C202506 C202507 \\\n", "0 2.0 2.0 1.0 2.0 3.0 ... 7.0 17.0 \n", "1 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 \n", "2 0.0 0.0 0.0 0.0 0.0 ... 3.0 4.0 \n", "3 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 \n", "4 0.0 1.0 3.0 0.0 0.0 ... 1.0 1.0 \n", "\n", " C202508 C202509 C202510 C202511 C202512 C202513 C202514 C202515 \n", "0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 \n", "1 0.0 0.0 0.0 0.0 0.0 2.0 1.0 0.0 \n", "2 0.0 4.0 4.0 2.0 1.0 6.0 0.0 0.0 \n", "3 0.0 0.0 0.0 1.0 1.0 1.0 0.0 0.0 \n", "4 0.0 2.0 2.0 3.0 2.0 5.0 0.0 0.0 \n", "\n", "[5 rows x 21 columns]" ] }, "execution_count": 26, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "# 1. Agrupamento horizontalizando as vendas por ciclo. transformando coluna de cilos em cada ciclo por coluna.\n", "df_agrupado = dfi.groupby(['PDV', 'SKU_FINAL', 'DESCRICAO', 'Ciclo'], as_index=False)['VENDAS_CICLO'].sum()\n", "\n", "# 2. Pivotar o DataFrame\n", "df_pivotado = df_agrupado.pivot_table(\n", " index=['PDV', 'SKU_FINAL', 'DESCRICAO'],\n", " columns='Ciclo',\n", " values='VENDAS_CICLO',\n", " fill_value=0 # Substitui NaN por 0\n", ")\n", "\n", "# 3. Resetar o índice para deixar como DataFrame normal (opcional)\n", "df_pivotadowawa = df_pivotado.reset_index()\n", "\n", "# 4. (Opcional) Renomear colunas com prefixo \"Ciclo_\"\n", "df_pivotadowawa.columns.name = None\n", "df_pivotadowawa = df_pivotadowawa.rename(columns=lambda x: f'Ciclo_{x}' if isinstance(x, (int, str)) and str(x).isdigit() else x)\n", "\n", "# Resultado final\n", "df_pivotadowawa.head()" ] }, { "cell_type": "code", "execution_count": 27, "id": "82cdeaed", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2.2.3\n" ] } ], "source": [ "import pandas as pd\n", "print(pd.__version__)\n" ] }, { "cell_type": "code", "execution_count": 28, "id": "8289d835", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\3920982216.py:25: UserWarning: pandas only supports SQLAlchemy connectable (engine/connection) or database string URI or sqlite3 DBAPI2 connection. Other DBAPI2 objects are not tested. Please consider using SQLAlchemy.\n", " df_draft_ = pd.read_sql(query_est_draft, conn)\n" ] } ], "source": [ "conn = pyodbc.connect(\n", " f\"DRIVER={{SQL Server}};\"\n", " f\"SERVER={config['banco']['host']},1433;\"\n", " f\"DATABASE=GINSENG;\"\n", " f\"UID={config['banco']['user']};\"\n", " f\"PWD={config['banco']['password']}\"\n", ")\n", "\n", "query_est_draft = f'''\n", "select em.PDV ,\n", "COALESCE(cast(em.SKU_PARA as int) , cast(em.SKU as int)) as SKU,\n", "em.DESCRICAO,\n", "d.salescurve as curva,\n", "d.codcategory as categoria,\n", "d.nextcycleprojection as proj_mar\n", ",d.secondtonextcycleprojection as 'proj_mar+1',\n", "em.[ESTOQUE ATUAL],em.[ESTOQUE EM TRANSITO],\n", "em.[PEDIDO PENDENTE],\n", "em.[DDV PREVISTO] ,\n", "d.pricesellin as 'preço'\n", "from estoque_mar em \n", "left join draft d on d.code = COALESCE(cast(em.SKU_PARA as int) , cast(em.SKU as int)) and d.loja_id = em.PDV \n", "where em.ORIGEM = 'BOT'\n", "'''\n", "df_draft_ = pd.read_sql(query_est_draft, conn)\n", "conn.close()\n", "\n" ] }, { "cell_type": "code", "execution_count": 29, "id": "dd49288f", "metadata": {}, "outputs": [], "source": [ "df_draft = df_draft_" ] }, { "cell_type": "code", "execution_count": 30, "id": "b110a12f", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOcurvacategoriaproj_marproj_mar+1ESTOQUE ATUALESTOQUE EM TRANSITOPEDIDO PENDENTEDDV PREVISTOpreço
02099857438MAKE B BAT GLOSS C/AC POLIGL CORAL 3,6gEMAQUIAGEM1.03.00.00.00.00,0418.29
12099881628MAKE B BAT GLOSS C/AC POLIGL NUDE 3,6gCMAQUIAGEM1.00.01.00.00.00,0218.29
22099881621MAKE B BAT MATE C/AC POLIG ORANGE FEV 4gCMAQUIAGEM0.00.010.00.00.0016.66
32099855984MAKE B BAT ST/PREN HYAL CAND TOF V3 3,4gCMAQUIAGEM1.00.09.00.00.00,0221.67
42099858566MAKE B CORRET LIQ FAC EFFECT 10 5,7mlCMAQUIAGEM2.01.00.01.01.0None15.30
\n", "
" ], "text/plain": [ " PDV SKU DESCRICAO curva categoria \\\n", "0 20998 57438 MAKE B BAT GLOSS C/AC POLIGL CORAL 3,6g E MAQUIAGEM \n", "1 20998 81628 MAKE B BAT GLOSS C/AC POLIGL NUDE 3,6g C MAQUIAGEM \n", "2 20998 81621 MAKE B BAT MATE C/AC POLIG ORANGE FEV 4g C MAQUIAGEM \n", "3 20998 55984 MAKE B BAT ST/PREN HYAL CAND TOF V3 3,4g C MAQUIAGEM \n", "4 20998 58566 MAKE B CORRET LIQ FAC EFFECT 10 5,7ml C MAQUIAGEM \n", "\n", " proj_mar proj_mar+1 ESTOQUE ATUAL ESTOQUE EM TRANSITO PEDIDO PENDENTE \\\n", "0 1.0 3.0 0.0 0.0 0.0 \n", "1 1.0 0.0 1.0 0.0 0.0 \n", "2 0.0 0.0 10.0 0.0 0.0 \n", "3 1.0 0.0 9.0 0.0 0.0 \n", "4 2.0 1.0 0.0 1.0 1.0 \n", "\n", " DDV PREVISTO preço \n", "0 0,04 18.29 \n", "1 0,02 18.29 \n", "2 0 16.66 \n", "3 0,02 21.67 \n", "4 None 15.30 " ] }, "execution_count": 30, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_draft.head()" ] }, { "cell_type": "code", "execution_count": 31, "id": "67dd3c27", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\2417376295.py:4: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_draft['ESTOQUE ATUAL'] = df_draft['ESTOQUE ATUAL'].astype(float)\n", "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\2417376295.py:6: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_draft['ESTOQUE EM TRANSITO'] = df_draft['ESTOQUE EM TRANSITO'].astype(float)\n", "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\2417376295.py:8: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_draft['PEDIDO PENDENTE'] = df_draft['PEDIDO PENDENTE'].astype(float)\n" ] }, { "data": { "text/plain": [ "(278761, 12)" ] }, "execution_count": 31, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# REMOVENDO OUI DOS PRODUTOS BOTI\n", "df_draft = df_draft[~df_draft['DESCRICAO'].str.contains('OUI', na=False)]\n", "\n", "df_draft['ESTOQUE ATUAL'] = df_draft['ESTOQUE ATUAL'].astype(float)\n", "\n", "df_draft['ESTOQUE EM TRANSITO'] = df_draft['ESTOQUE EM TRANSITO'].astype(float)\n", "\n", "df_draft['PEDIDO PENDENTE'] = df_draft['PEDIDO PENDENTE'].astype(float)\n", "\n", "df_draft.shape" ] }, { "cell_type": "code", "execution_count": 32, "id": "355778d6", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\1952797845.py:1: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_draft['DDV PREVISTO'] = df_draft['DDV PREVISTO'].str.replace(',','.')\n", "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\1952797845.py:3: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_draft['DDV PREVISTO'] = df_draft['DDV PREVISTO'].astype(float)\n", "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\1952797845.py:5: SettingWithCopyWarning: \n", "A value is trying to be set on a copy of a slice from a DataFrame.\n", "Try using .loc[row_indexer,col_indexer] = value instead\n", "\n", "See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy\n", " df_draft['DDV PREVISTO'] = df_draft['DDV PREVISTO'].fillna(0)\n" ] } ], "source": [ "df_draft['DDV PREVISTO'] = df_draft['DDV PREVISTO'].str.replace(',','.')\n", "\n", "df_draft['DDV PREVISTO'] = df_draft['DDV PREVISTO'].astype(float)\n", "\n", "df_draft['DDV PREVISTO'] = df_draft['DDV PREVISTO'].fillna(0)" ] }, { "cell_type": "code", "execution_count": 33, "id": "d891c575", "metadata": {}, "outputs": [], "source": [ "#agrupamento pra evitar duplicidade\n", "df_draft = df_draft.groupby(['PDV','SKU','curva','categoria'])[['proj_mar','proj_mar+1','ESTOQUE ATUAL','ESTOQUE EM TRANSITO','PEDIDO PENDENTE','DDV PREVISTO','preço']].max().reset_index()" ] }, { "cell_type": "code", "execution_count": 34, "id": "3d13ef4c", "metadata": {}, "outputs": [], "source": [ "df_draft['SKU'] = df_draft['SKU'].astype('Int64')" ] }, { "cell_type": "code", "execution_count": 35, "id": "5ca66c75", "metadata": {}, "outputs": [], "source": [ "df_draft = pd.merge(df_draft,df_pivotadowawa,left_on=['PDV','SKU'],right_on=['PDV','SKU_FINAL'],how='inner')" ] }, { "cell_type": "code", "execution_count": 36, "id": "91298cde", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['C202415', 'C202416', 'C202417', 'C202501', 'C202502', 'C202503',\n", " 'C202504', 'C202505', 'C202506', 'C202507', 'C202508', 'C202509',\n", " 'C202510', 'C202511', 'C202512', 'C202513', 'C202514', 'C202515'],\n", " dtype='object')" ] }, "execution_count": 36, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# OLHO COLUNAS DE VENDA\n", "df_draft.columns[13:31]" ] }, { "cell_type": "code", "execution_count": 37, "id": "34e179cb", "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "C:\\Users\\joao.herculano\\AppData\\Local\\Temp\\ipykernel_28176\\1731143361.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[13:31]\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": 38, "id": "94aa432f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 58363\n", "1 58363\n", "2 58363\n", "3 58363\n", "4 58363\n", "Name: PRODUTO SIMILAR, dtype: Int64" ] }, "execution_count": 38, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_similares['PRODUTO SIMILAR'] = df_similares['PRODUTO SIMILAR'].astype('Int64')\n", "df_similares['PRODUTO SIMILAR'].head()" ] }, { "cell_type": "code", "execution_count": 39, "id": "38b0eb5d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PDV object\n", "SKU Int64\n", "dtype: object" ] }, "execution_count": 39, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_draft[['PDV', 'SKU']].dtypes" ] }, { "cell_type": "code", "execution_count": 40, "id": "4bc8c2b4", "metadata": {}, "outputs": [], "source": [ "df_draft['PDV'] = df_draft['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": 41, "id": "2c9f011d", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "PRODUTO SIMILAR\n", "58363 76\n", "Name: count, dtype: Int64" ] }, "execution_count": 41, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_similares= df_similares[df_similares['PRODUTO SIMILAR'].notna()]\n", "\n", "df_similares['PRODUTO SIMILAR'].value_counts()" ] }, { "cell_type": "code", "execution_count": 42, "id": "0ff66803", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "SKU\n", "58363 75\n", "Name: count, dtype: Int64" ] }, "execution_count": 42, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final['SKU'].value_counts()" ] }, { "cell_type": "code", "execution_count": 43, "id": "64bde00b", "metadata": {}, "outputs": [], "source": [ "df_venda_diaria = pd.read_csv(\n", " r\"../../SUPRIMENTOS/BD_LANÇAMENTOS/BOT/arquivos usados por todos os lançamentos/vendas 20250815.csv\",\n", " sep=';',\n", " dtype={'SKU_2': str},decimal=',')" ] }, { "cell_type": "code", "execution_count": 44, "id": "6ab155b5", "metadata": {}, "outputs": [], "source": [ "df_venda_diaria['VENDAS_CICLO'] = df_venda_diaria['VENDAS_CICLO'].str.replace(r'\\.', '', regex=True)" ] }, { "cell_type": "code", "execution_count": 45, "id": "1d25e5df", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOVENDAS_CICLOCiclo
01252251.944COFFEE DES COL MAN SEDUC TCH PRM 10ml11C202307
12099877.557QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK1C202405
22085874.103GLAMOUR DES COL SEC BL 75ml V45C202409
3569947.950ZAAD EDP 95ml V612C202406
42099350.297ESTJ DEM LILY ESSENCE 4x4ml2C202416
\n", "
" ], "text/plain": [ " PDV SKU DESCRICAO VENDAS_CICLO \\\n", "0 12522 51.944 COFFEE DES COL MAN SEDUC TCH PRM 10ml 11 \n", "1 20998 77.557 QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK 1 \n", "2 20858 74.103 GLAMOUR DES COL SEC BL 75ml V4 5 \n", "3 5699 47.950 ZAAD EDP 95ml V6 12 \n", "4 20993 50.297 ESTJ DEM LILY ESSENCE 4x4ml 2 \n", "\n", " Ciclo \n", "0 C202307 \n", "1 C202405 \n", "2 C202409 \n", "3 C202406 \n", "4 C202416 " ] }, "execution_count": 45, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_venda_diaria.head()" ] }, { "cell_type": "code", "execution_count": 46, "id": "5d0d79f2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOVendas_TotalCiclo
01252251.944COFFEE DES COL MAN SEDUC TCH PRM 10ml11C202307
12099877.557QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK1C202405
22085874.103GLAMOUR DES COL SEC BL 75ml V45C202409
3569947.950ZAAD EDP 95ml V612C202406
42099350.297ESTJ DEM LILY ESSENCE 4x4ml2C202416
\n", "
" ], "text/plain": [ " PDV SKU DESCRICAO Vendas_Total \\\n", "0 12522 51.944 COFFEE DES COL MAN SEDUC TCH PRM 10ml 11 \n", "1 20998 77.557 QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK 1 \n", "2 20858 74.103 GLAMOUR DES COL SEC BL 75ml V4 5 \n", "3 5699 47.950 ZAAD EDP 95ml V6 12 \n", "4 20993 50.297 ESTJ DEM LILY ESSENCE 4x4ml 2 \n", "\n", " Ciclo \n", "0 C202307 \n", "1 C202405 \n", "2 C202409 \n", "3 C202406 \n", "4 C202416 " ] }, "execution_count": 46, "metadata": {}, "output_type": "execute_result" } ], "source": [ "#df_venda_diaria['Ciclo'] = df_venda_diaria['Ciclo'].str.replace(\"C\",\"C20\") \n", "\n", "df_venda_diaria = df_venda_diaria.rename(columns={'VENDAS_CICLO':'Vendas_Total'})\n", "\n", "df_venda_diaria.head()" ] }, { "cell_type": "code", "execution_count": 47, "id": "a93427da", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOVendas_TotalCiclo
01252251.944COFFEE DES COL MAN SEDUC TCH PRM 10ml11C202307
12099877.557QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK1C202405
22085874.103GLAMOUR DES COL SEC BL 75ml V45C202409
3569947.950ZAAD EDP 95ml V612C202406
42099350.297ESTJ DEM LILY ESSENCE 4x4ml2C202416
\n", "
" ], "text/plain": [ " PDV SKU DESCRICAO Vendas_Total \\\n", "0 12522 51.944 COFFEE DES COL MAN SEDUC TCH PRM 10ml 11 \n", "1 20998 77.557 QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK 1 \n", "2 20858 74.103 GLAMOUR DES COL SEC BL 75ml V4 5 \n", "3 5699 47.950 ZAAD EDP 95ml V6 12 \n", "4 20993 50.297 ESTJ DEM LILY ESSENCE 4x4ml 2 \n", "\n", " Ciclo \n", "0 C202307 \n", "1 C202405 \n", "2 C202409 \n", "3 C202406 \n", "4 C202416 " ] }, "execution_count": 47, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_venda_diaria['Vendas_Total'] = df_venda_diaria['Vendas_Total'].str.replace(',', '.', regex=False)\n", "\n", "df_venda_diaria['Vendas_Total'] = df_venda_diaria['Vendas_Total'].astype('float')\n", "\n", "df_venda_diaria['Vendas_Total'] = round(df_venda_diaria['Vendas_Total'],0)\n", "\n", "df_venda_diaria['Vendas_Total'] = df_venda_diaria['Vendas_Total'].astype(str)\n", "\n", "df_venda_diaria['Vendas_Total'] = (\n", " df_venda_diaria['Vendas_Total']\n", " .str.replace('.0', '', regex=False)\n", " .str.replace('.', '', regex=False)\n", " .astype('Int64')\n", ")\n", "\n", "\n", "df_venda_diaria.head()" ] }, { "cell_type": "code", "execution_count": 48, "id": "7d973983", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOVendas_TotalCiclo
\n", "
" ], "text/plain": [ "Empty DataFrame\n", "Columns: [PDV, SKU, DESCRICAO, Vendas_Total, Ciclo]\n", "Index: []" ] }, "execution_count": 48, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_venda_diaria[(df_venda_diaria['PDV']==14668) & (df_venda_diaria['SKU']=='85096')]" ] }, { "cell_type": "code", "execution_count": 49, "id": "6ddec856", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOVendas_TotalCiclo
01252251.944COFFEE DES COL MAN SEDUC TCH PRM 10ml11C202307
12099877.557QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK1C202405
22085874.103GLAMOUR DES COL SEC BL 75ml V45C202409
3569947.950ZAAD EDP 95ml V612C202406
42099350.297ESTJ DEM LILY ESSENCE 4x4ml2C202416
\n", "
" ], "text/plain": [ " PDV SKU DESCRICAO Vendas_Total \\\n", "0 12522 51.944 COFFEE DES COL MAN SEDUC TCH PRM 10ml 11 \n", "1 20998 77.557 QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK 1 \n", "2 20858 74.103 GLAMOUR DES COL SEC BL 75ml V4 5 \n", "3 5699 47.950 ZAAD EDP 95ml V6 12 \n", "4 20993 50.297 ESTJ DEM LILY ESSENCE 4x4ml 2 \n", "\n", " Ciclo \n", "0 C202307 \n", "1 C202405 \n", "2 C202409 \n", "3 C202406 \n", "4 C202416 " ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_venda_diaria2 = df_venda_diaria.pivot_table(\n", " index=[\"PDV\", \"SKU\", \"DESCRICAO\"],\n", " columns=\"Ciclo\",\n", " values=\"Vendas_Total\",\n", " fill_value=0\n", ").reset_index()\n", "\n", "# Se quiser, reorganize as colunas colocando os ciclos ao final\n", "df_venda_diaria.columns.name = None\n", "\n", "df_venda_diaria.head()" ] }, { "cell_type": "code", "execution_count": 50, "id": "882e68aa", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['PDV', 'SKU', 'DESCRICAO', 'Vendas_Total', 'Ciclo'], dtype='object')" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_venda_diaria.columns" ] }, { "cell_type": "code", "execution_count": 51, "id": "0c288d75", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOVendas_TotalCiclo
01252251.944COFFEE DES COL MAN SEDUC TCH PRM 10ml11C202307
12099877.557QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK1C202405
22085874.103GLAMOUR DES COL SEC BL 75ml V45C202409
3569947.950ZAAD EDP 95ml V612C202406
42099350.297ESTJ DEM LILY ESSENCE 4x4ml2C202416
..................
16633152099683.039QUASAR DES COL RUSH 100ml1C202415
16633162097052.025BOTI BABY SAB LIQ GLIC V2 400ml6C202511
16633172099693.069LA PIEL D/COL SPR CP PER AMBR DOUR 200ml10C202414
16633181342751.279MAKE B BAS LIQ C/ GLYC TX 140 30g1C202309
16633192127852.014CJ FLAC OUI EDP ICONIQUE INTENSE 3x1ml2C202511
\n", "

1663320 rows × 5 columns

\n", "
" ], "text/plain": [ " PDV SKU DESCRICAO \\\n", "0 12522 51.944 COFFEE DES COL MAN SEDUC TCH PRM 10ml \n", "1 20998 77.557 QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK \n", "2 20858 74.103 GLAMOUR DES COL SEC BL 75ml V4 \n", "3 5699 47.950 ZAAD EDP 95ml V6 \n", "4 20993 50.297 ESTJ DEM LILY ESSENCE 4x4ml \n", "... ... ... ... \n", "1663315 20996 83.039 QUASAR DES COL RUSH 100ml \n", "1663316 20970 52.025 BOTI BABY SAB LIQ GLIC V2 400ml \n", "1663317 20996 93.069 LA PIEL D/COL SPR CP PER AMBR DOUR 200ml \n", "1663318 13427 51.279 MAKE B BAS LIQ C/ GLYC TX 140 30g \n", "1663319 21278 52.014 CJ FLAC OUI EDP ICONIQUE INTENSE 3x1ml \n", "\n", " Vendas_Total Ciclo \n", "0 11 C202307 \n", "1 1 C202405 \n", "2 5 C202409 \n", "3 12 C202406 \n", "4 2 C202416 \n", "... ... ... \n", "1663315 1 C202415 \n", "1663316 6 C202511 \n", "1663317 10 C202414 \n", "1663318 1 C202309 \n", "1663319 2 C202511 \n", "\n", "[1663320 rows x 5 columns]" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_venda_diaria" ] }, { "cell_type": "code", "execution_count": 52, "id": "bdf6abbb", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "CICLO SIMILAR object\n", "PRODUTO SIMILAR Int64\n", "PDV int64\n", "dtype: object" ] }, "execution_count": 52, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final[['CICLO SIMILAR','PRODUTO SIMILAR','PDV']].dtypes" ] }, { "cell_type": "code", "execution_count": 53, "id": "dc452c72", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(76, 61)" ] }, "execution_count": 53, "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": 54, "id": "c9de258b", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PRODUTO LANÇAMENTODESCRIÇÃO DO LANÇAMENTOPRODUTO SIMILARDESCRIÇÃO SIMILARCICLO SIMILARFOCOIAFCATEGORIAMARCA% CONSUMIDOR...C202513C202514C202515CRESCIMENTOCicloINICIO CICLOFIM CICLODURAÇÃOmatchdias_ate_inicio
086116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...4.00.00.0-0.1178C2025172025-12-012025-12-2525145
186116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...12.03.00.0-0.1177C2025172025-12-012025-12-2525145
286116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...3.01.00.0-0.0883C2025172025-12-012025-12-2525145
386116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...2.00.00.0-0.1160C2025172025-12-012025-12-2525145
486116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...9.00.00.0-0.1009C2025172025-12-012025-12-2525145
\n", "

5 rows × 61 columns

\n", "
" ], "text/plain": [ " PRODUTO LANÇAMENTO DESCRIÇÃO DO LANÇAMENTO \\\n", "0 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "1 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "2 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "3 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "4 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "\n", " PRODUTO SIMILAR DESCRIÇÃO SIMILAR \\\n", "0 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "1 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "2 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "3 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "4 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "\n", " CICLO SIMILAR FOCO IAF CATEGORIA MARCA % CONSUMIDOR ... C202513 \\\n", "0 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... 4.0 \n", "1 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... 12.0 \n", "2 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... 3.0 \n", "3 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... 2.0 \n", "4 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... 9.0 \n", "\n", " C202514 C202515 CRESCIMENTO Ciclo INICIO CICLO FIM CICLO DURAÇÃO match \\\n", "0 0.0 0.0 -0.1178 C202517 2025-12-01 2025-12-25 25 1 \n", "1 3.0 0.0 -0.1177 C202517 2025-12-01 2025-12-25 25 1 \n", "2 1.0 0.0 -0.0883 C202517 2025-12-01 2025-12-25 25 1 \n", "3 0.0 0.0 -0.1160 C202517 2025-12-01 2025-12-25 25 1 \n", "4 0.0 0.0 -0.1009 C202517 2025-12-01 2025-12-25 25 1 \n", "\n", " dias_ate_inicio \n", "0 45 \n", "1 45 \n", "2 45 \n", "3 45 \n", "4 45 \n", "\n", "[5 rows x 61 columns]" ] }, "execution_count": 54, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final.head()" ] }, { "cell_type": "code", "execution_count": 55, "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": 56, "id": "cc65edab", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOVendas Ciclo LançamentoCiclo
01252251.944COFFEE DES COL MAN SEDUC TCH PRM 10ml11C202307
12099877.557QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK1C202405
22085874.103GLAMOUR DES COL SEC BL 75ml V45C202409
3569947.950ZAAD EDP 95ml V612C202406
42099350.297ESTJ DEM LILY ESSENCE 4x4ml2C202416
\n", "
" ], "text/plain": [ " PDV SKU DESCRICAO \\\n", "0 12522 51.944 COFFEE DES COL MAN SEDUC TCH PRM 10ml \n", "1 20998 77.557 QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK \n", "2 20858 74.103 GLAMOUR DES COL SEC BL 75ml V4 \n", "3 5699 47.950 ZAAD EDP 95ml V6 \n", "4 20993 50.297 ESTJ DEM LILY ESSENCE 4x4ml \n", "\n", " Vendas Ciclo Lançamento Ciclo \n", "0 11 C202307 \n", "1 1 C202405 \n", "2 5 C202409 \n", "3 12 C202406 \n", "4 2 C202416 " ] }, "execution_count": 56, "metadata": {}, "output_type": "execute_result" } ], "source": [ "\n", "df_venda_diaria = df_venda_diaria.rename(columns={'Vendas_Total':'Vendas Ciclo Lançamento'})\n", "df_venda_diaria.head()" ] }, { "cell_type": "code", "execution_count": 57, "id": "6367ac21", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 C202506\n", "28 C202506\n", "56 C202506\n", "84 C202506\n", "112 C202506\n", " ... \n", "1988 C202506\n", "2016 C202506\n", "2044 C202506\n", "2072 C202506\n", "2100 C202506\n", "Name: CICLO SIMILAR, Length: 76, dtype: object" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final['CICLO SIMILAR'] = df_final['CICLO SIMILAR'].fillna('0')\n", "df_final['CICLO SIMILAR'] " ] }, { "cell_type": "code", "execution_count": 58, "id": "b0af59cb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CICLO SIMILARPRODUTO SIMILARPDV
0C2025065836312522
28C2025065836312817
56C2025065836312818
84C2025065836312820
112C2025065836312823
\n", "
" ], "text/plain": [ " CICLO SIMILAR PRODUTO SIMILAR PDV\n", "0 C202506 58363 12522\n", "28 C202506 58363 12817\n", "56 C202506 58363 12818\n", "84 C202506 58363 12820\n", "112 C202506 58363 12823" ] }, "execution_count": 58, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final[['CICLO SIMILAR','PRODUTO SIMILAR','PDV']].head()" ] }, { "cell_type": "code", "execution_count": 59, "id": "72925ca7", "metadata": {}, "outputs": [], "source": [ "\n", "\n", "df_final['PRODUTO SIMILAR'] = df_final['PRODUTO SIMILAR'].astype('Int64')\n", "\n" ] }, { "cell_type": "code", "execution_count": 60, "id": "8b0bb174", "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', 'CANAL',\n", " 'DESCRIÇÃO PDV', 'PDV DESC', 'UF', 'ANALISTA', 'SUPERVISOR', 'STATUS',\n", " 'ANALISTA EUD', 'SKU', 'curva', 'categoria', 'proj_mar', 'proj_mar+1',\n", " 'ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO', 'PEDIDO PENDENTE',\n", " 'DDV PREVISTO', 'preço', 'SKU_FINAL', 'DESCRICAO', 'C202415', 'C202416',\n", " 'C202417', 'C202501', 'C202502', 'C202503', 'C202504', 'C202505',\n", " 'C202506', 'C202507', 'C202508', 'C202509', 'C202510', 'C202511',\n", " 'C202512', 'C202513', 'C202514', 'C202515', 'CRESCIMENTO', 'Ciclo_x',\n", " 'INICIO CICLO_x', 'FIM CICLO_x', 'DURAÇÃO_x', 'match',\n", " 'dias_ate_inicio', 'Ciclo_y', 'INICIO CICLO_y', 'FIM CICLO_y',\n", " 'DURAÇÃO_y'],\n", " dtype='object')" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final.columns" ] }, { "cell_type": "code", "execution_count": 61, "id": "1efff472", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKUDESCRICAOVendas Ciclo LançamentoCiclo
01252251944COFFEE DES COL MAN SEDUC TCH PRM 10ml11C202307
12099877557QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK1C202405
22085874103GLAMOUR DES COL SEC BL 75ml V45C202409
3569947950ZAAD EDP 95ml V612C202406
42099350297ESTJ DEM LILY ESSENCE 4x4ml2C202416
\n", "
" ], "text/plain": [ " PDV SKU DESCRICAO \\\n", "0 12522 51944 COFFEE DES COL MAN SEDUC TCH PRM 10ml \n", "1 20998 77557 QDB BASE LIQ SUPERMAT COR 06 Q 30ml RPCK \n", "2 20858 74103 GLAMOUR DES COL SEC BL 75ml V4 \n", "3 5699 47950 ZAAD EDP 95ml V6 \n", "4 20993 50297 ESTJ DEM LILY ESSENCE 4x4ml \n", "\n", " Vendas Ciclo Lançamento Ciclo \n", "0 11 C202307 \n", "1 1 C202405 \n", "2 5 C202409 \n", "3 12 C202406 \n", "4 2 C202416 " ] }, "execution_count": 61, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_venda_diaria['SKU'] = df_venda_diaria['SKU'].astype('str')\n", "\n", "df_venda_diaria['SKU'] = df_venda_diaria['SKU'].str.replace('.','')\n", "\n", "df_venda_diaria.head()" ] }, { "cell_type": "code", "execution_count": 62, "id": "62ea79f7", "metadata": {}, "outputs": [], "source": [ "df_final['PRODUTO SIMILAR'] = df_final['PRODUTO SIMILAR'].astype('str')" ] }, { "cell_type": "code", "execution_count": 63, "id": "c5cd5f42", "metadata": {}, "outputs": [], "source": [ "df_final = pd.merge(left=df_final, right = df_venda_diaria[['PDV','SKU','Ciclo','Vendas Ciclo Lançamento']], right_on=['Ciclo','SKU','PDV'],left_on=['CICLO SIMILAR','PRODUTO SIMILAR','PDV'],how='left')\n", "\n", "df_final = df_final.drop_duplicates()" ] }, { "cell_type": "code", "execution_count": 64, "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": 65, "id": "69c88d20", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "np.int64(1)" ] }, "execution_count": 65, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final['PDV'].value_counts().min()" ] }, { "cell_type": "code", "execution_count": 66, "id": "f5206f50", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO', 'PEDIDO PENDENTE',\n", " 'DDV PREVISTO', 'preço', 'SKU_FINAL', 'DESCRICAO', 'C202415', 'C202416',\n", " 'C202417', 'C202501', 'C202502', 'C202503', 'C202504', 'C202505',\n", " 'C202506', 'C202507'],\n", " dtype='object')" ] }, "execution_count": 66, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final.columns[29:46]" ] }, { "cell_type": "code", "execution_count": 67, "id": "5e33d293", "metadata": {}, "outputs": [], "source": [ "df_jacobina = pd.read_excel(r\"../../SUPRIMENTOS/BD_LANÇAMENTOS/BOT/arquivos usados por todos os lançamentos/draft unificado.xlsx\")" ] }, { "cell_type": "code", "execution_count": 68, "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": 69, "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": 70, "id": "d3dc8c38", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PDVSKU202408202409202410202411202412202413202414202415202416202417202501202502202503202504202505202506202507
0242694901410511122113040210
1242684901410442513443024201
22426949016363111014221119122100
324268490161231222003114304210
424269481413223953241331110674102
\n", "
" ], "text/plain": [ " PDV SKU 202408 202409 202410 202411 202412 202413 202414 \\\n", "0 24269 49014 1 0 5 1 1 1 2 \n", "1 24268 49014 1 0 4 4 2 5 1 \n", "2 24269 49016 36 3 1 1 1 0 14 \n", "3 24268 49016 12 3 1 2 2 2 0 \n", "4 24269 48141 32 2 3 95 3 2 41 \n", "\n", " 202415 202416 202417 202501 202502 202503 202504 202505 202506 \\\n", "0 2 1 1 3 0 4 0 2 1 \n", "1 3 4 4 3 0 2 4 2 0 \n", "2 2 2 1 1 19 1 2 2 10 \n", "3 0 3 11 4 3 0 4 2 1 \n", "4 3 3 1 1 1 0 67 4 10 \n", "\n", " 202507 \n", "0 0 \n", "1 1 \n", "2 0 \n", "3 0 \n", "4 2 " ] }, "execution_count": 70, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_jacobina.head()" ] }, { "cell_type": "code", "execution_count": 71, "id": "4169aba0", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
PRODUTO LANÇAMENTODESCRIÇÃO DO LANÇAMENTOPRODUTO SIMILARDESCRIÇÃO SIMILARCICLO SIMILARFOCOIAFCATEGORIAMARCA% CONSUMIDOR...DURAÇÃO_xmatchdias_ate_inicioCiclo_yINICIO CICLO_yFIM CICLO_yDURAÇÃO_ySKU_yCicloVendas Ciclo Lançamento
086116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...25145C2025062025-04-142025-05-112858363C20250640
186116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...25145C2025062025-04-142025-05-112858363C202506102
286116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...25145C2025062025-04-142025-05-112858363C20250615
386116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...25145C2025062025-04-142025-05-112858363C20250613
486116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...58363Body Splash Desodrante Colônia Cuide-se Bem Nu...C202506NãoNãoPERFUMARIACUIDE-SE BEM-...25145C2025062025-04-142025-05-112858363C20250624
\n", "

5 rows × 68 columns

\n", "
" ], "text/plain": [ " PRODUTO LANÇAMENTO DESCRIÇÃO DO LANÇAMENTO \\\n", "0 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "1 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "2 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "3 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "4 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "\n", " PRODUTO SIMILAR DESCRIÇÃO SIMILAR \\\n", "0 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "1 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "2 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "3 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "4 58363 Body Splash Desodrante Colônia Cuide-se Bem Nu... \n", "\n", " CICLO SIMILAR FOCO IAF CATEGORIA MARCA % CONSUMIDOR ... \\\n", "0 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... \n", "1 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... \n", "2 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... \n", "3 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... \n", "4 C202506 Não Não PERFUMARIA CUIDE-SE BEM - ... \n", "\n", " DURAÇÃO_x match dias_ate_inicio Ciclo_y INICIO CICLO_y FIM CICLO_y \\\n", "0 25 1 45 C202506 2025-04-14 2025-05-11 \n", "1 25 1 45 C202506 2025-04-14 2025-05-11 \n", "2 25 1 45 C202506 2025-04-14 2025-05-11 \n", "3 25 1 45 C202506 2025-04-14 2025-05-11 \n", "4 25 1 45 C202506 2025-04-14 2025-05-11 \n", "\n", " DURAÇÃO_y SKU_y Ciclo Vendas Ciclo Lançamento \n", "0 28 58363 C202506 40 \n", "1 28 58363 C202506 102 \n", "2 28 58363 C202506 15 \n", "3 28 58363 C202506 13 \n", "4 28 58363 C202506 24 \n", "\n", "[5 rows x 68 columns]" ] }, "execution_count": 71, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final['PRODUTO SIMILAR'] = df_final['PRODUTO SIMILAR'].astype('Int64')\n", "\n", "df_final.head()" ] }, { "cell_type": "code", "execution_count": 72, "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": 73, "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": 74, "id": "dcff1fcb", "metadata": {}, "outputs": [], "source": [ "df_final = df_final.fillna(0)" ] }, { "cell_type": "code", "execution_count": 75, "id": "bebabb9f", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['C202415', 'C202416', 'C202417', 'C202501', 'C202502', 'C202503',\n", " 'C202504', 'C202505', 'C202506', 'C202507', 'C202508', 'C202509',\n", " 'C202510', 'C202511', 'C202512', 'C202513', 'C202514', 'C202515'],\n", " dtype='object')" ] }, "execution_count": 75, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# VERIFICAR SE TEM OS 17 CICLOS DE VENDA\n", "df_final.columns[36:54]" ] }, { "cell_type": "code", "execution_count": 76, "id": "0a1bb832", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.2" ] }, "execution_count": 76, "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[36:54]\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", "CRESCIMENTO = 0.2 if CRESCIMENTO < 0.2 else CRESCIMENTO\n", "\n", "df_final['CRESCIMENTO_GERAL'] = CRESCIMENTO\n", "\n", "CRESCIMENTO\n" ] }, { "cell_type": "code", "execution_count": 77, "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": 78, "id": "b107e519", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['C202509', 'C202510', 'C202511', 'C202512', 'C202513', 'C202514',\n", " 'C202515'],\n", " dtype='object')" ] }, "execution_count": 78, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# VERIFICAR SE AS 6 ULTIMAS COLUNAS SÃO DE VENDA CICLO\n", "df_final.columns[47:54]" ] }, { "cell_type": "code", "execution_count": 79, "id": "8290853c", "metadata": {}, "outputs": [], "source": [ "VENDA_SIMILAR_6_MESES= df_final.columns[47:54]\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": 80, "id": "d8b30560", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 0.0\n", "1 1.0\n", "2 0.0\n", "3 0.0\n", "4 0.0\n", " ... \n", "71 0.0\n", "72 0.0\n", "73 0.0\n", "74 0.0\n", "75 0.0\n", "Length: 76, dtype: float64" ] }, "execution_count": 80, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final[colunas_mensais].median(axis=1, skipna=True)\n" ] }, { "cell_type": "code", "execution_count": 81, "id": "07f043f2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CANALUFPRODUTO LANÇAMENTOmed_por_canal
0CDAL861160.0
1HIBAL861161.0
2HIBBA861161.0
3HIBSE861160.5
4LJAL861161.0
5LJBA861160.5
6LJSE861160.5
7VDAL861164.5
8VDBA861162.0
9VDSE861164.0
\n", "
" ], "text/plain": [ " CANAL UF PRODUTO LANÇAMENTO med_por_canal\n", "0 CD AL 86116 0.0\n", "1 HIB AL 86116 1.0\n", "2 HIB BA 86116 1.0\n", "3 HIB SE 86116 0.5\n", "4 LJ AL 86116 1.0\n", "5 LJ BA 86116 0.5\n", "6 LJ SE 86116 0.5\n", "7 VD AL 86116 4.5\n", "8 VD BA 86116 2.0\n", "9 VD SE 86116 4.0" ] }, "execution_count": 81, "metadata": {}, "output_type": "execute_result" } ], "source": [ "medi = df_final.groupby(['CANAL','UF','PRODUTO LANÇAMENTO'])['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": 82, "id": "ef979be5", "metadata": {}, "outputs": [], "source": [ "df_dourado = pd.read_excel(r\"../../SUPRIMENTOS/BD_LANÇAMENTOS/BOT/arquivos usados por todos os lançamentos/compilado de vendas.xlsx\")\n", "\n", "df_dourado['Data de venda'] = pd.to_datetime(df_dourado['Data de venda'], dayfirst=True)\n", "\n", "df_dourado['de para pdv'] = df_dourado['de para pdv'].astype(str)\n", "\n", "df_dourado['de para pdv'] = df_dourado['de para pdv'].str.replace(r'\\.0$', '', regex=True)\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=['PDV', 'SKU', 'Ciclo'])\n", "\n", "# Calcula a quantidade acumulada até o dia para cada grupo\n", "df_dourado['Quantidade Acumulada dourado'] = (\n", " df_dourado\n", " .groupby(['de para pdv', 'sku'])['Quantidade Vendida']\n", " .cumsum()\n", ") # acumulado por grupo até a data da linha\n", "\n", "df_dourado = pd.merge(left=df_dourado,right=calendario[['Date','Ciclo']],left_on='Data de venda',right_on='Date',how='inner')\n", "\n", "\n", "\n", "df_dourado_agrupado = df_dourado.groupby(['de para pdv','sku','Ciclo'])['Quantidade Acumulada dourado'].max().reset_index()\n", "\n", "df_dourado_agrupado = df_dourado_agrupado.rename(columns={'Ciclo':'Ciclo dourado'})\n", "\n" ] }, { "cell_type": "code", "execution_count": 83, "id": "41eb7ebf", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0 12522\n", "1 12817\n", "2 12818\n", "3 12820\n", "4 12823\n", "Name: PDV, dtype: object" ] }, "execution_count": 83, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final['PDV'] = df_final['PDV'].astype(str)\n", "df_final['PDV'].head()" ] }, { "cell_type": "code", "execution_count": 84, "id": "6dbe67bb", "metadata": {}, "outputs": [], "source": [ "df_final = pd.merge(left=df_final, right = df_dourado_agrupado, right_on=['Ciclo dourado','sku','de para pdv'],left_on=['CICLO SIMILAR','PRODUTO SIMILAR','PDV'],how='left')\n", "\n", "df_final['Quantidade Acumulada dourado'] = df_final['Quantidade Acumulada dourado'].fillna(0)\n", "\n", "\n", "df_final['Vendas Ciclo Lançamento'] = np.where(df_final['Quantidade Acumulada dourado'] > 0, df_final['Quantidade Acumulada dourado'], df_final['Vendas Ciclo Lançamento'])\n", "\n", "df_final = df_final.drop(columns='Quantidade Acumulada dourado')\n", "\n", "\n", "df_final = df_final.drop(columns='Ciclo dourado')" ] }, { "cell_type": "code", "execution_count": 85, "id": "7986b8fa", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CP VIVA BEMProtheusPDVDEPARA.PracticoCanalEndereçoCNPJCNPJ Locação
0355970101.023713.0MATRIZ - LJRua Zeferino Correia, nº 17, Centro, CEP 45.00...14.378.160/0001-8314.378.160/0001-83
1729270103.023712.0LOJAAl. Rio Branco, nº 373, Centro, Cândido Sales ...14.378.160/0006-9814.378.160/0006-98
2870870102.023711.0VDAl. Lima Guerra, nº 04, Centro, Vitória da Con...14.378.160/0005-0714.378.160/0001-83
38931NaN23710.0NaNAvenida Rosa Cruz, nº 80, Hiper B Preço Loja B...14.378.160/0008-5014.378.160/0008-50
41119170108.023709.0LOJAAv. Juracy Magalhães, nº 3340, Shopping Conqui...14.378.160/0009-3014.378.160/0001-83
\n", "
" ], "text/plain": [ " CP VIVA BEM Protheus PDVDEPARA.Practico Canal \\\n", "0 3559 70101.0 23713.0 MATRIZ - LJ \n", "1 7292 70103.0 23712.0 LOJA \n", "2 8708 70102.0 23711.0 VD \n", "3 8931 NaN 23710.0 NaN \n", "4 11191 70108.0 23709.0 LOJA \n", "\n", " Endereço CNPJ \\\n", "0 Rua Zeferino Correia, nº 17, Centro, CEP 45.00... 14.378.160/0001-83 \n", "1 Al. Rio Branco, nº 373, Centro, Cândido Sales ... 14.378.160/0006-98 \n", "2 Al. Lima Guerra, nº 04, Centro, Vitória da Con... 14.378.160/0005-07 \n", "3 Avenida Rosa Cruz, nº 80, Hiper B Preço Loja B... 14.378.160/0008-50 \n", "4 Av. Juracy Magalhães, nº 3340, Shopping Conqui... 14.378.160/0009-30 \n", "\n", " CNPJ Locação \n", "0 14.378.160/0001-83 \n", "1 14.378.160/0006-98 \n", "2 14.378.160/0001-83 \n", "3 14.378.160/0008-50 \n", "4 14.378.160/0001-83 " ] }, "execution_count": 85, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_depara_vdc = pd.read_excel(r\"../../SUPRIMENTOS/BD_LANÇAMENTOS/BOT/arquivos usados por todos os lançamentos/Filiais - Vitoria da Conquista 4.xlsx\")\n", "\n", "df_depara_vdc.head()" ] }, { "cell_type": "code", "execution_count": 86, "id": "84b5917c", "metadata": {}, "outputs": [], "source": [ "df_final['PRODUTO SIMILAR'] = df_final['PRODUTO SIMILAR'].astype('Int64')" ] }, { "cell_type": "code", "execution_count": 87, "id": "1a625e69", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(76, 92)" ] }, "execution_count": 87, "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", " 0,\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(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": 88, "id": "30c1d83d", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Index(['202408', '202409', '202410', '202411', '202412', '202413', '202414',\n", " '202415', '202416', '202417', '202501', '202502', '202503', '202504',\n", " '202505', '202506', '202507'],\n", " dtype='object')\n" ] } ], "source": [ "# verificar as vendas dos ciclos\n", "print(df_final.columns[68:85])" ] }, { "cell_type": "code", "execution_count": 89, "id": "62b7f9d1", "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', 'CANAL',\n", " 'DESCRIÇÃO PDV', 'PDV DESC', 'UF', 'ANALISTA', 'SUPERVISOR', 'STATUS',\n", " 'ANALISTA EUD', 'SKU_x', 'curva', 'categoria', 'proj_mar', 'proj_mar+1',\n", " 'ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO', 'PEDIDO PENDENTE',\n", " 'DDV PREVISTO', 'preço', 'SKU_FINAL', 'DESCRICAO', 'C202415', 'C202416',\n", " 'C202417', 'C202501', 'C202502', 'C202503', 'C202504', 'C202505',\n", " 'C202506', 'C202507', 'C202508', 'C202509', 'C202510', 'C202511',\n", " 'C202512', 'C202513', 'C202514', 'C202515', 'CRESCIMENTO', 'Ciclo',\n", " 'INICIO CICLO', 'FIM CICLO', 'DURAÇÃO', 'match', 'dias_ate_inicio',\n", " 'INICIO CICLO SIMILAR', 'FIM CICLO SIMILAR', 'DURAÇÃO CICLO SIMILAR',\n", " 'SKU_y', 'Ciclo', 'Vendas Ciclo Lançamento', 'SKU', 'CRESCIMENTO_GERAL',\n", " 'Pico Vendas Similar Ultimos 6 ciclos', 'MEDIANA DO HISTÓRICO',\n", " 'de para pdv', 'sku', 'CRESCIMENTO_FINAL', 'PV GINSENG'],\n", " dtype='object')" ] }, "execution_count": 89, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import re\n", "\n", "# identificar colunas de ciclo puro (ex: '202407')\n", "colunas_ciclo_puro = [col for col in df_final.columns[68:85]]\n", "\n", "for col in colunas_ciclo_puro:\n", " col_hist = f'C{col}'\n", " if col_hist in df_final.columns:\n", " # mantém o maior valor entre a coluna histórica e a pura\n", " df_final[col_hist] = df_final[[col_hist, col]].max(axis=1)\n", "\n", "# remove as colunas puras\n", "if colunas_ciclo_puro:\n", " df_final.drop(columns=colunas_ciclo_puro, inplace=True)\n", "\n", "df_final.columns" ] }, { "cell_type": "code", "execution_count": 90, "id": "3b7f3a82", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['C202511', 'C202512', 'C202513', 'C202514', 'C202515'], dtype='object')" ] }, "execution_count": 90, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final.columns[49:54]" ] }, { "cell_type": "code", "execution_count": 91, "id": "d63e55c4", "metadata": {}, "outputs": [], "source": [ "df_final['Pico Vendas Similar Ultimos 6 ciclos'] = df_final[VENDA_SIMILAR_6_MESES].max(axis=1)" ] }, { "cell_type": "code", "execution_count": 92, "id": "15b7149f", "metadata": {}, "outputs": [], "source": [ "df_final = df_final.rename(columns={df_final.columns[49]: \"C-4\", df_final.columns[50]: \"C-3\",df_final.columns[51]: \"C-2\",df_final.columns[52]: \"C-1\",df_final.columns[53]:'VENDAS CICLO ATUAL'})\n" ] }, { "cell_type": "code", "execution_count": 93, "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', 'CANAL',\n", " 'DESCRIÇÃO PDV', 'PDV DESC', 'UF', 'ANALISTA', 'SUPERVISOR', 'STATUS',\n", " 'ANALISTA EUD', 'SKU_X', 'CURVA', 'CATEGORIA', 'PROJ_MAR', 'PROJ_MAR+1',\n", " 'ESTOQUE ATUAL', 'ESTOQUE EM TRANSITO', 'PEDIDO PENDENTE',\n", " 'DDV PREVISTO', 'PREÇO', 'SKU_FINAL', 'DESCRICAO', 'C202415', 'C202416',\n", " 'C202417', 'C202501', 'C202502', 'C202503', 'C202504', 'C202505',\n", " 'C202506', 'C202507', 'C202508', 'C202509', 'C202510', 'C-4', 'C-3',\n", " 'C-2', 'C-1', 'VENDAS CICLO ATUAL', 'CRESCIMENTO', 'CICLO',\n", " 'INICIO CICLO', 'FIM CICLO', 'DURAÇÃO', 'MATCH', 'DIAS_ATE_INICIO',\n", " 'INICIO CICLO SIMILAR', 'FIM CICLO SIMILAR', 'DURAÇÃO CICLO SIMILAR',\n", " 'CICLO', 'VENDAS CICLO LANÇAMENTO', 'SKU', 'CRESCIMENTO_GERAL',\n", " 'PICO VENDAS SIMILAR ULTIMOS 6 CICLOS', 'MEDIANA DO HISTÓRICO',\n", " 'DE PARA PDV', 'SKU', 'CRESCIMENTO_FINAL', 'PV GINSENG'],\n", " dtype='object')" ] }, "execution_count": 93, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final.columns = df_final.columns.str.upper()\n", "\n", "df_final.drop(columns=df_final.filter(regex='_Y').columns, inplace=True)\n", "\n", "df_final.columns" ] }, { "cell_type": "code", "execution_count": 94, "id": "dceebd16", "metadata": {}, "outputs": [], "source": [ "df_final = df_final.rename(columns={'MARCA_X':'MARCA'})" ] }, { "cell_type": "code", "execution_count": 95, "id": "62ce5c62", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(76, 74)" ] }, "execution_count": 95, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final.shape" ] }, { "cell_type": "code", "execution_count": 96, "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": 97, "id": "8ad318b0", "metadata": {}, "outputs": [], "source": [ "df_final = df_final.loc[:, ~df_final.columns.duplicated()]\n", "\n", "colunas_desejadas = [\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", " 'CURVA',\n", " 'CATEGORIA',\n", " '% CONSUMIDOR',\n", " 'MECANICA CONSUMIDOR',\n", " '% REVENDEDOR',\n", " 'MECANICA 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", "]\n", "\n", "df_final = df_final.reindex(columns=colunas_desejadas)\n", "\n", "colunas_filtradas = [col for col in colunas_desejadas if col in df_final.columns]\n", "df_final = df_final[colunas_filtradas]\n" ] }, { "cell_type": "code", "execution_count": 98, "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": 99, "id": "cc9c6ee6", "metadata": {}, "outputs": [], "source": [ "df_pdv_origi['PDV'] = df_pdv_origi['PDV'].astype(str)\n", "\n", "df_pdv_origi['PDV'].head()\n", "\n", "df_pdv_origi = df_pdv_origi.rename(columns={'UF':'UF_CERTO'})" ] }, { "cell_type": "code", "execution_count": 100, "id": "df9f0130", "metadata": {}, "outputs": [], "source": [ "#adicionando o UF correto ao fim do script\n", "df_final= pd.merge(df_final,df_pdv_origi[['UF_CERTO','PDV']],on='PDV',how='inner')" ] }, { "cell_type": "code", "execution_count": 101, "id": "f8cd886a", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
SUPERVISORANALISTACANALUFPDVDESCRIÇÃO PDVPRODUTO LANÇAMENTODESCRIÇÃO DO LANÇAMENTOMARCACURVA...C-4C-3C-2C-1VENDAS CICLO ATUALPICO VENDAS SIMILAR ULTIMOS 6 CICLOSPV GINSENGSUGESTÃO METASELLINSUGESTÃO ABASTECIMENTOSUGESTÃO COMERCIAL
0Efigênia HerculanoLUANLJAL12522MACEIO SHOP EXP86116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...CUIDE-SE BEMA...7.05.04.00.00.08.048
1Maxwell VieiraJEFFERSONLJAL12817SHOPPING PATIO86116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...CUIDE-SE BEMB...39.07.012.03.00.039.0122
2Maxwell VieiraVINICIUSLJAL12818GB SERRARIA86116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...CUIDE-SE BEMB...5.01.03.01.00.05.018
3Maxwell VieiraADRIELYLJAL12820ATACADÃO86116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...CUIDE-SE BEMB...8.00.02.00.00.08.016
4Efigênia HerculanoADRIELYLJAL12823PONTA VERDE86116CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ...CUIDE-SE BEMA...14.011.09.00.00.014.029
\n", "

5 rows × 32 columns

\n", "
" ], "text/plain": [ " SUPERVISOR ANALISTA CANAL UF PDV DESCRIÇÃO PDV \\\n", "0 Efigênia Herculano LUAN LJ AL 12522 MACEIO SHOP EXP \n", "1 Maxwell Vieira JEFFERSON LJ AL 12817 SHOPPING PATIO \n", "2 Maxwell Vieira VINICIUS LJ AL 12818 GB SERRARIA \n", "3 Maxwell Vieira ADRIELY LJ AL 12820 ATACADÃO \n", "4 Efigênia Herculano ADRIELY LJ AL 12823 PONTA VERDE \n", "\n", " PRODUTO LANÇAMENTO DESCRIÇÃO DO LANÇAMENTO \\\n", "0 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "1 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "2 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "3 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "4 86116 CUIDE-SE BEM DOCES DELÍRIOS ALGODÃO DOCE BODY ... \n", "\n", " MARCA CURVA ... C-4 C-3 C-2 C-1 VENDAS CICLO ATUAL \\\n", "0 CUIDE-SE BEM A ... 7.0 5.0 4.0 0.0 0.0 \n", "1 CUIDE-SE BEM B ... 39.0 7.0 12.0 3.0 0.0 \n", "2 CUIDE-SE BEM B ... 5.0 1.0 3.0 1.0 0.0 \n", "3 CUIDE-SE BEM B ... 8.0 0.0 2.0 0.0 0.0 \n", "4 CUIDE-SE BEM A ... 14.0 11.0 9.0 0.0 0.0 \n", "\n", " PICO VENDAS SIMILAR ULTIMOS 6 CICLOS PV GINSENG SUGESTÃO METASELLIN \\\n", "0 8.0 48 \n", "1 39.0 122 \n", "2 5.0 18 \n", "3 8.0 16 \n", "4 14.0 29 \n", "\n", " SUGESTÃO ABASTECIMENTO SUGESTÃO COMERCIAL \n", "0 \n", "1 \n", "2 \n", "3 \n", "4 \n", "\n", "[5 rows x 32 columns]" ] }, "execution_count": 101, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final['UF']= df_final['UF_CERTO']\n", "\n", "df_final = df_final.drop(columns=['UF_CERTO'])\n", "\n", "df_final.head()" ] }, { "cell_type": "code", "execution_count": 102, "id": "eaf25e4b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Index(['SUPERVISOR', 'ANALISTA', 'CANAL', 'UF', 'PDV', 'DESCRIÇÃO PDV',\n", " 'PRODUTO LANÇAMENTO', 'DESCRIÇÃO DO LANÇAMENTO', 'MARCA', 'CURVA',\n", " 'CATEGORIA', '% CONSUMIDOR', 'MECANICA CONSUMIDOR', '% REVENDEDOR',\n", " 'MECANICA REVENDEDOR', 'TIPO DE PRODUTO', 'IAF', 'FOCO',\n", " 'PRODUTO SIMILAR', 'DESCRIÇÃO SIMILAR', 'CICLO SIMILAR',\n", " 'VENDAS CICLO LANÇAMENTO', 'C-4', 'C-3', 'C-2', 'C-1',\n", " 'VENDAS CICLO ATUAL', 'PICO VENDAS SIMILAR ULTIMOS 6 CICLOS',\n", " 'PV GINSENG', 'SUGESTÃO METASELLIN', 'SUGESTÃO ABASTECIMENTO',\n", " 'SUGESTÃO COMERCIAL'],\n", " dtype='object')" ] }, "execution_count": 102, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final.columns" ] }, { "cell_type": "code", "execution_count": 103, "id": "9b866c74", "metadata": {}, "outputs": [], "source": [ "\n", "# lista de colunas numéricas\n", "numeric_cols = [\n", " 'VENDAS CICLO LANÇAMENTO', 'C-4', 'C-3', 'C-2', 'C-1',\n", " 'VENDAS CICLO ATUAL', 'PICO VENDAS SIMILAR ULTIMOS 6 CICLOS',\n", " 'PV GINSENG', 'SUGESTÃO METASELLIN', 'SUGESTÃO ABASTECIMENTO',\n", " 'SUGESTÃO COMERCIAL'\n", "]\n", "\n", "# colunas não numéricas = todas menos as numéricas\n", "non_numeric_cols = [col for col in df_final.columns if col not in numeric_cols]\n", "\n", "# agrupar por todas as não numéricas, pegando o máximo das numéricas\n", "df_final_sem_dupli = (\n", " df_final\n", " .groupby(non_numeric_cols, as_index=False)[numeric_cols]\n", " .sum()\n", ")\n" ] }, { "cell_type": "code", "execution_count": 104, "id": "88d0d6de", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "['C:',\n", " 'Users',\n", " 'joao.herculano',\n", " 'GRUPO GINSENG',\n", " 'Assistência Suprimentos - 2025',\n", " 'SUPRIMENTOS',\n", " 'BD_LANÇAMENTOS',\n", " 'BOT',\n", " 'BOT - C17',\n", " 'arquivos para geração da sugestão']" ] }, "execution_count": 104, "metadata": {}, "output_type": "execute_result" } ], "source": [ "arquivo_similares.split('\\\\')[0:-2]" ] }, { "cell_type": "code", "execution_count": 105, "id": "03af489b", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'C:\\\\Users\\\\joao.herculano\\\\GRUPO GINSENG\\\\Assistência Suprimentos - 2025\\\\SUPRIMENTOS\\\\BD_LANÇAMENTOS\\\\BOT\\\\BOT - C17\\\\arquivos para geração da sugestão'" ] }, "execution_count": 105, "metadata": {}, "output_type": "execute_result" } ], "source": [ "caminho_out =arquivo_similares.split('\\\\')[0:-2]\n", "\n", "resultado_out = \"\\\\\".join(caminho_out)\n", "resultado_out" ] }, { "cell_type": "code", "execution_count": 106, "id": "8fdb44f5", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "CURVA\n", "B 63\n", "A 10\n", "C 2\n", "0 1\n", "Name: count, dtype: int64" ] }, "execution_count": 106, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final_sem_dupli['CURVA'].value_counts()" ] }, { "cell_type": "code", "execution_count": 107, "id": "c69f7a57", "metadata": {}, "outputs": [], "source": [ "df_final_sem_dupli['CURVA'] = df_final_sem_dupli['CURVA'].astype('str')" ] }, { "cell_type": "code", "execution_count": 108, "id": "56d7ec83", "metadata": {}, "outputs": [], "source": [ "df_final_sem_dupli['CURVA'] = df_final_sem_dupli['CURVA'].str.replace('0','E')" ] }, { "cell_type": "code", "execution_count": 109, "id": "231f00a0", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "CURVA\n", "B 63\n", "A 10\n", "C 2\n", "E 1\n", "Name: count, dtype: int64" ] }, "execution_count": 109, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_final_sem_dupli['CURVA'].value_counts()" ] }, { "cell_type": "code", "execution_count": 110, "id": "2df3e2e9", "metadata": {}, "outputs": [], "source": [ "#df_final_sem_dupli.to_excel(f'{resultado_out}\\\\LANCAMENTO_{hoje}.xlsx',index=False)" ] }, { "cell_type": "code", "execution_count": 111, "id": "b1566a14", "metadata": {}, "outputs": [], "source": [ "# Export to Excel\n", "output_file = f'{resultado_out}\\\\LANCAMENTO_{hoje}.xlsx'\n", "with pd.ExcelWriter(output_file, engine='openpyxl') as writer:\n", " df_final_sem_dupli.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='366092', end_color='366092', 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)" ] } ], "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 }