2
respostas

[Sugestão] Desafio: identificando fraudes

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def detectar_outliers_iqr_otimizado(coluna, df):
    """
    Detecta e visualiza outliers em uma coluna numérica usando o método IQR,
    com código mais compacto e sem perda de funcionalidade.
    """
    # Validações básicas (mantidas para robustez)
    if coluna not in df.columns:
        raise ValueError(f"A coluna '{coluna}' não existe no DataFrame.")
    if not pd.api.types.is_numeric_dtype(df[coluna]):
        raise TypeError(f"A coluna '{coluna}' precisa ser numérica para aplicar o método IQR.")

    df_analisado = df.copy()

    # Cálculo do IQR e dos limites
    Q1 = df_analisado[coluna].quantile(0.25)
    Q3 = df_analisado[coluna].quantile(0.75)
    IQR = Q3 - Q1
    limite_inferior = Q1 - 1.5 * IQR
    limite_superior = Q3 + 1.5 * IQR

    # Exibe os valores de cálculo
    print("\n--- Análise Estatística (Cálculo IQR) ---")
    print(f"Q1 (25º percentil): {Q1}")
    print(f"Q3 (75º percentil): {Q3}")
    print(f"IQR (Q3 - Q1): {IQR}")
    print(f"Limite Superior: {limite_superior}")
    print(f"Limite Inferior: {limite_inferior}")
    print("------------------------------------------")

    # Lógica de filtragem otimizada usando operador de negação (~)
    dados_corretos = df_analisado[
        (df_analisado[coluna] >= limite_inferior) & (df_analisado[coluna] <= limite_superior)
    ].reset_index(drop=True)
    
    outliers = df_analisado[
        ~((df_analisado[coluna] >= limite_inferior) & (df_analisado[coluna] <= limite_superior))
    ].reset_index(drop=True)

    # Estatísticas
    total = len(df_analisado)
    total_corretos = len(dados_corretos)
    total_outliers = len(outliers)
    
    print(f"\nAnálise da Coluna: {coluna}")
    print(f"Total de dados analisados: {total}")
    print(f"Total de dados corretos: {total_corretos}")
    print(f"Total de outliers: {total_outliers}")
    
    # ... (o restante do código, incluindo a impressão e os gráficos, pode ser mantido igual) ...
    # Exemplo:
    # print("\nTransações Corretas:")
    # print(dados_corretos)
    # print("\nOutliers Encontrados:")
    # print(outliers)
    
    plt.figure(figsize=(14, 6))
    plt.subplot(1, 2, 1)
    sns.boxplot(data=df_analisado, y=coluna)
    plt.title('Boxplot com Outliers (Dados Originais)')

    plt.subplot(1, 2, 2)
    sns.boxplot(data=dados_corretos, y=coluna, showfliers=False)
    plt.title('Boxplot sem Outliers (Visão Pura)')

    plt.tight_layout()
    plt.show()

    return dados_corretos, outliers

if __name__ == '__main__':
    df = pd.DataFrame({
        'ID da transação': range(1, 31),
        'Valor da transação': [100, 200, 150, 500, 300, 913, 250, 400, 200, 150,
                               200, 200, 400, 300, 150, 301, 805, 300, 400, 250,
                               150, 100, 500, 600, 200, 350, 100, 250, 800, 250],
        'Data da transação': pd.date_range(start='2022-01-01', end='2022-01-30', freq='D'),
        'Local da transação': [
            'São Paulo, Brasil', 'Rio de Janeiro, Brasil', 'Belo Horizonte, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'Nova Iorque, EUA', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'Rio de Janeiro, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'Los Angeles, EUA', 'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'Miami, EUA', 'São Paulo, Brasil'
        ]
    })

    dados_corretos, outliers = detectar_outliers_iqr_otimizado('Valor da transação', df)
2 respostas

V2

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

def detectar_outliers_iqr(coluna, df):
    """
    Detecta e visualiza outliers em uma coluna numérica usando o método IQR (Intervalo Interquartil).
    Aplica o filtro apenas uma vez, conforme a prática padrão.
    
    Parâmetros:
    coluna (str): Nome da coluna para análise.
    df (pd.DataFrame): O DataFrame a ser analisado.
    
    Retorna:
    tuple: Um tuple contendo dois DataFrames: (dados_corretos, outliers).
    """
    # Validações básicas
    if coluna not in df.columns:
        raise ValueError(f"A coluna '{coluna}' não existe no DataFrame.")
    if not pd.api.types.is_numeric_dtype(df[coluna]):
        raise TypeError(f"A coluna '{coluna}' precisa ser numérica para aplicar o método IQR.")

    df_analisado = df.copy()

    # Cálculo do IQR e dos limites de outliers em uma única etapa
    Q1 = df_analisado[coluna].quantile(0.25)
    Q3 = df_analisado[coluna].quantile(0.75)
    IQR = Q3 - Q1
    
    limite_inferior = Q1 - 1.5 * IQR
    limite_superior = Q3 + 1.5 * IQR

    # Exibe os valores de cálculo, como você solicitou
    print("\n--- Análise Estatística (Cálculo IQR) ---")
    print(f"Q1 (25º percentil): {Q1}")
    print(f"Q3 (75º percentil): {Q3}")
    print(f"IQR (Q3 - Q1): {IQR}")
    print(f"Limite Superior (Q3 + 1.5 * IQR): {Q3} + (1.5 * {IQR}) = {limite_superior}")
    print(f"Limite Inferior (Q1 - 1.5 * IQR): {Q1} - (1.5 * {IQR}) = {limite_inferior}")
    print("------------------------------------------")

    # Filtra os dados corretos e os outliers
    dados_corretos = df_analisado[(df_analisado[coluna] >= limite_inferior) & (df_analisado[coluna] <= limite_superior)]
    outliers = df_analisado[(df_analisado[coluna] < limite_inferior) | (df_analisado[coluna] > limite_superior)]
    
    # Resetando os índices para uma visualização limpa
    dados_corretos = dados_corretos.reset_index(drop=True)
    outliers = outliers.reset_index(drop=True)

    # Estatísticas
    total = len(df_analisado)
    total_corretos = len(dados_corretos)
    total_outliers = len(outliers)
    perc_corretos = (total_corretos / total) * 100
    perc_outliers = (total_outliers / total) * 100

    print(f"\nAnálise da Coluna: {coluna}")
    print(f"Total de dados analisados: {total}")
    print(f"Total de dados corretos: {total_corretos}")
    print(f"Total de outliers: {total_outliers}")
    print(f"Porcentagem de dados corretos: {perc_corretos:.2f}%")
    print(f"Porcentagem de outliers: {perc_outliers:.2f}%")

    print("\nTransações Corretas:")
    print(dados_corretos)

    print("\nOutliers Encontrados:")
    print(outliers)

    # Gráficos
    plt.figure(figsize=(14, 6))
    plt.subplot(1, 2, 1)
    sns.boxplot(data=df_analisado, y=coluna)
    plt.title('Boxplot com Outliers (Dados Originais)')

    plt.subplot(1, 2, 2)
    # AQUI ESTÁ A CORREÇÃO: showfliers=False remove os pontos isolados
    sns.boxplot(data=dados_corretos, y=coluna, showfliers=False) 
    plt.title('Boxplot sem Outliers (Visão Pura)')

    plt.tight_layout()
    plt.show()

    return dados_corretos, outliers

if __name__ == '__main__':
    df = pd.DataFrame({
        'ID da transação': range(1, 31),
        'Valor da transação': [100, 200, 150, 500, 300, 913, 250, 400, 200, 150,
                               200, 200, 400, 300, 150, 301, 805, 300, 400, 250,
                               150, 100, 500, 600, 200, 350, 100, 250, 800, 250],
        'Data da transação': pd.date_range(start='2022-01-01', end='2022-01-30', freq='D'),
        'Local da transação': [
            'São Paulo, Brasil', 'Rio de Janeiro, Brasil', 'Belo Horizonte, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'Nova Iorque, EUA', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'Rio de Janeiro, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'Los Angeles, EUA', 'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil', 'São Paulo, Brasil',
            'Miami, EUA', 'São Paulo, Brasil'
        ]
    })

    dados_corretos, outliers = detectar_outliers_iqr('Valor da transação', df)

Oi, Marinaldo! Tudo bom?

Excelente! Siga praticando com os desafios e sempre compartilhe conosco.

Você soube aplicar a técnica de detecção de outliers com IQR de forma eficiente, aproveitou o uso do showfliers=False no Seaborn para melhorar a visualização dos dados e entendeu como o tratamento de dados extremos é essencial para análises estatísticas confiáveis.

Permaneça postando as suas soluções, com certeza isso ajudará outros estudantes e tem grande relevância para o fórum.

Ícone de sugestão Para saber mais:

Sugestão de conteúdo para você mergulhar ainda mais sobre o tema:

Alguns materiais estão em inglês, mas é possível compreendê-los usando o recurso de tradução de páginas do próprio navegador.

Fico à disposição! E se precisar, conte sempre com o apoio do fórum.

Abraço e bons estudos!

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