1
resposta

Criar uma nova coluna com base em faixas de peso

Olá,

Tenho um DataFrame com duas colunas, PRODUTO e PESO:

PRODUTOPESO
TVNUMERO10.520
TVNUMERO21.560
TVNUMERO32.250

Quero adicionar novas colunas (CUSTO DE FRETE) para visualizar esse custo para cada produto dependendo do Estado do Brasil de destino. Esse custo de frete é calculado com base no peso do produto.

Os custos de frete estão em outro DataFrame da seguinte forma:

PESO INICIALPESO FINALVALOR DE FRETE SÃO PAULOVALOR DE FRETE PARANÁVALOR DE FRETE SANTA CATARINA
0.0010.5005.008.009.00
0.5011.00010.0012.0013.00
1.0013.00015.0018.0019.00

Mas não faço ideia de como fazer criar essas nova colunas no primeiro DataFrame, buscando as informações que tem essa condição de PESO INICIAL e PESO FINAL. Qual a melhor forma para criar essas novas colunas?

1 resposta

Oi Robson,

Existe uma forma de fazer isso utilizando o Numpy em conjunto com o Pandas. A função que permite esse truque é a piecewise e podemos dizer que ela permite que criemos uma espécie de join personalizado.

Vamos ao código.

import pandas as pd
import numpy as np

df_produto = pd.DataFrame({
    'PRODUTO': ['TVNUMERO1', 'TVNUMERO2', 'TVNUMERO3', 'TVNUMERO4', 'TVNUMERO5', 'TVNUMERO6'],
    'PESO': [0.520, 1.560, 0.250, 0.015, 2.000, 0.780]
})
df_produto

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Note que eu adicionei algumas informações extras nos seus DataFrames para deixar o funcionamento do código mais claro no nosso exemplo.

df_base = pd.DataFrame([
    [0.001,    0.500,    5.00,    8.00,    9.00],
    [0.501,    0.750,    7.00,    9.00,    11.00],
    [0.751,    1.000,    10.00,    12.00,    13.00],
    [1.001,    3.000,    15.00,    18.00,    19.00]
], columns=['PESO INICIAL', 'PESO FINAL', 'VALOR DE FRETE SÃO PAULO', 'VALOR DE FRETE PARANÁ', 'VALOR DE FRETE SANTA CATARINA'])
df_base

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

pesos_limites = zip(df_base['PESO INICIAL'].values, df_base['PESO FINAL'].values)
condicoes = [
    (df_produto.PESO.values >= peso_inicial) & (df_produto.PESO.values <= peso_final) for peso_inicial, peso_final in pesos_limites
]
condicoes

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

No código acima criamos uma lista de condições onde são testados se cada peso de df_produto está entre os pesos das colunas de referência em df_base. Funciona como lustrado na imagem abaixo:

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

O próximo passo é utilizar a função piecewise passando como parâmetros um array de ZEROS com a mesma dimensão do DataFrame df_produto, as condições que criamos acima e a coluna do DataFrame df_base que queremos juntar.

Note que coloquei no resultado final as colunas PESO INICIAL e PESO FINAL apenas para você verificar o funcionamento do processo.

df_produto['PESO INICIAL'] = np.piecewise(np.zeros(len(df_produto)), condicoes, df_base['PESO INICIAL'].values)
df_produto['PESO FINAL'] = np.piecewise(np.zeros(len(df_produto)), condicoes, df_base['PESO FINAL'].values)
df_produto['VALOR DE FRETE SÃO PAULO'] = np.piecewise(np.zeros(len(df_produto)), condicoes, df_base['VALOR DE FRETE SÃO PAULO'].values)
df_produto['VALOR DE FRETE PARANÁ'] = np.piecewise(np.zeros(len(df_produto)), condicoes, df_base['VALOR DE FRETE PARANÁ'].values)
df_produto['VALOR DE FRETE SANTA CATARINA'] = np.piecewise(np.zeros(len(df_produto)), condicoes, df_base['VALOR DE FRETE SANTA CATARINA'].values)
df_produto

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Espero ter ajudado