Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

[Sugestão] Por que segui uma abordagem diferente na limpeza da coluna `conta.cobranca.Total`?

Olá pessoal,

Nessa etapa do projeto, tive a oportunidade de comparar minha abordagem com a do instrutor — e acabei encontrando uma divergência importante que me fez seguir um caminho diferente.

Ponto inicial semelhante

Assim como o instrutor, comecei analisando os registros com valores vazios ou inconsistentes na coluna 'conta.cobranca.Total':

dados_normalizados[dados_normalizados['conta.cobranca.Total'] == ' '].head()

Mas algo chamou minha atenção...

Ao investigar melhor os dados, percebi uma incoerência: nem todos os clientes com contrato de "dois anos" tinham exatamente 24 meses registrados em cliente.tempo_servico.

Então executei essa linha:

dados_normalizados.loc[
    dados_normalizados['conta.contrato'] == 'dois anos', 
    'cliente.tempo_servico'
].value_counts(dropna=False)

E o resultado foi esse:

72.0    353
71.0    142
       ... 
1.0       2
28.0      1
Name: count, Length: 74, dtype: int64

Isso mostrou que:

  • 74 valores distintos de cliente.tempo_servico associados ao contrato de "dois anos"
  • O valor mais comum foi 72 meses (6 anos), não 24
  • Outros registros variavam desde 1 até 71 meses

Conclusão da análise

Identifiquei que:

  • A informação "dois anos" na coluna conta.contrato nem sempre corresponde a 24 meses no campo cliente.tempo_servico.
  • Na verdade, muitas vezes ela representa contratos bem mais antigos (como 6 anos).
  • Isso indica que o campo cliente.tempo_servico representa o tempo real de uso do serviço, enquanto conta.contrato parece ser apenas o tipo de plano contratado.

Portanto, atribuir 24 meses automaticamente seria incorreto nesse caso.

Minha abordagem alternativa

Com base nessa descoberta, optei por seguir um caminho mais seguro e fundamentado nos próprios dados:

  1. Preenchi valores ausentes em colunas numéricas com zero
dados_normalizados = dados_normalizados.fillna({
    'cliente.tempo_servico': 0,
    'conta.cobranca.mensal': 0
})
  1. Criei uma máscara para identificar valores inválidos em conta.cobranca.Total
cols = ['cliente.tempo_servico', 'conta.contrato', 'conta.cobranca.mensal', 'conta.cobranca.Total']

pattern = r'^\d+(\.\d+)?$'  # Aceita números inteiros ou decimais

mask = (
    dados_normalizados['conta.cobranca.Total'].isna() |
    ~dados_normalizados['conta.cobranca.Total'].str.match(pattern, na=False)
)
  1. Atualizei os valores com base no cálculo real entre tempo de serviço e mensalidade
idx = dados_normalizados.loc[mask, cols].index

dados_normalizados.loc[idx, 'conta.cobranca.Total'] = (
    dados_normalizados.loc[idx, 'cliente.tempo_servico'] *
    dados_normalizados.loc[idx, 'conta.cobranca.mensal']
)
  1. Converti a coluna para float no final
dados_normalizados['conta.cobranca.Total'] = dados_normalizados['conta.cobranca.Total'].astype(float)

Resultado final

Após a transformação, a coluna 'conta.cobranca.Total' ficou consistente e alinhada com os dados reais do cliente:

dados_normalizados.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7344 entries, 0 to 7343
Data columns (total 21 columns):
 #   Column                         Non-Null Count  Dtype  
---  ------                         --------------  -----  
                         ...                               
 6   cliente.tempo_servico          7344 non-null   float64
                         ...                               
 19  conta.cobranca.mensal          7344 non-null   float64
 20  conta.cobranca.Total           7344 non-null   float64
dtypes: float64(3), int64(1), object(17)
memory usage: 1.2+ MB

Amostra de linhas alteradas:

dados_normalizados.loc[idx, cols]
conta.contratocliente.tempo_servicoconta.cobranca.mensalconta.cobranca.Total
None9.00.000.0
None18.020.05360.9
dois anos0.080.850.0
dois anos60.020.951257.0

Considerações finais

Essa experiência reforçou a importância de explorar os dados antes de aplicar transformações fixas. Às vezes, a lógica aparentemente mais simples pode esconder nuances importantes — como a diferença entre tempo contratado e tempo efetivo de serviço.

Abraço!

2 respostas
solução!

Oi Carlos, tudo bem?

Que interessante a sua abordagem! É realmente importante explorar os dados antes de aplicar transformações fixas, como você mencionou. A diferença entre o tempo contratado e o tempo efetivo de serviço é uma nuance que pode passar despercebida, mas que é crucial para a análise correta dos dados.

Continue asim!

Uma dica interessante para o futuro é utilizar o método pd.to_numeric com o parâmetro errors='coerce', que ajuda a converter strings numéricas com segurança, tratando automaticamente valores inválidos como NaN. Veja este exemplo:


dados_normalizados['conta.cobranca.Total'] = pd.to_numeric(
    dados_normalizados['conta.cobranca.Total'], errors='coerce'
)

Esse código tenta converter os valores da coluna para float e substitui valores não numéricos por NaN, facilitando a limpeza posterior.

Qualquer dúvida que surgir, compartilhe no fórum. Abraços e bons estudos!

Conteúdos relacionados

A documentação está em inglês, mas você poderá utilizar a tradução automática do navegador.

Alura

Conte com o apoio da comunidade Alura na sua jornada. Abraços e bons estudos!

Olá, Monalisa.

Obrigado pelo retorno positivo e pela dica do pd.to_numeric() com errors='coerce'. É o tipo de detalhe que facilita a vida na hora de limpar dados com inconsistências.

É bom saber que a postagem foi útil.

Abraço!