Uso de IA no trabalho

Peça à IA regras para limpar um CSV e revise cada célula alterada

Use um assistente de chat com IA para propor regras explícitas de limpeza de dados, aplique apenas as regras aprovadas a uma cópia do CSV e gere um registro de antes/depois por célula. O exemplo é sintético para que você possa revisar cada transformação manualmente.

Ver o sumário

A tradução foi feita com IA. Confira o código, as unidades e os valores junto com o original. A revisão por falantes nativos de cada idioma ainda não foi concluída. English

Para quem éPara quem quer usar IA para definir regras repetíveis de limpeza de CSV sem permitir que a IA reescreva os dados silenciosamente.

Preparação
  • Python 3.12
  • Um editor de texto e um assistente de chat com IA

01Comece com um CSV sintético pequeno

Este exemplo usa pessoas e endereços de e-mail sintéticos; nenhum dos registros é real. O objetivo não é pedir à IA que limpe o arquivo diretamente. Em vez disso, peça que ela descreva regras que você possa revisar, aprovar e aplicar de forma determinística.

Salve o conteúdo a seguir como sample_people.csv. Observe os espaços inconsistentes, as diferenças de maiúsculas e minúsculas em email e department, o marcador de valor ausente e a formatação numérica.

text
row_id,name,email,department,hours
1, alice kim ,ALICE.KIM@example.com, sales ,8
2,Bob Lee,bob.lee@example.com,Engineering,7.5
3,Carol Park, carol.park@example.com ,SALES, 8.0
4,Dan Choi,,engineering,NA
5,Eve Han,eve.han@example.com, Sales,9

02Peça regras à IA, não um arquivo reescrito

Explique à IA o significado das colunas e forneça alguns valores representativos. Peça que ela separe alterações seguras de formatação de transformações que possam mudar o significado dos dados.

Não aprove uma regra apenas porque ela parece razoável. Por exemplo, converter todos os nomes para Title Case pode alterar uma capitalização válida. Da mesma forma, substituir todos os valores vazios de hours por zero adicionaria informação que não existia na fonte.

03Transforme a resposta da IA em uma tabela de regras explícitas

Uma resposta conservadora da IA para este exemplo pode sugerir regras como as seguintes. Revise cada uma antes de escrever o código.

ColunaRegra aprovadaMotivo
nameRemover apenas espaços no início e no fimRemove espaços acidentais sem alterar maiúsculas e minúsculas
emailRemover espaços e depois converter valores não vazios para minúsculasNormaliza os endereços do exemplo sem inventar valores ausentes
departmentApós remover espaços, mapear sales para Sales e engineering para Engineering sem diferenciar maiúsculas e minúsculasUsa uma lista fechada visível no exemplo
hoursRemover espaços; converter NA em vazio; normalizar uma notação decimal válidaTorna consistentes o marcador de ausência escolhido e a representação numérica
row_idNão alterarPreserva a identidade do registro

Essas regras são intencionalmente restritas. Valores desconhecidos de department devem permanecer como estão, em vez de serem adivinhados. E-mails vazios continuam vazios. Nenhuma linha é excluída e nenhum registro é deduplicado.

04Preveja as alterações antes de executar qualquer coisa

Em um exemplo pequeno, calcule manualmente o resultado esperado. Assim, você terá uma referência para comparar com a saída do script.

row_idColunaAntesDepois
1name alice kim alice kim
1emailALICE.KIM@example.comalice.kim@example.com
1department sales Sales
3email carol.park@example.com carol.park@example.com
3departmentSALESSales
3hours 8.08
4departmentengineeringEngineering
4hoursNA
5department SalesSales

Portanto, exatamente 9 células devem mudar. A row 2 deve permanecer inalterada, e o script deve manter as 5 linhas na ordem original.

05Aplique apenas as regras aprovadas a uma cópia

O script a seguir, baseado apenas na biblioteca padrão, valida as colunas esperadas, limpa cada linha e registra todas as células cujo valor muda. Ele para se outputs já existir, reduzindo o risco de substituir silenciosamente uma revisão anterior.

python
import csv
import sys
from decimal import Decimal, InvalidOperation
from pathlib import Path

INPUT = Path("sample_people.csv")
OUTPUT_DIR = Path("outputs")
CLEANED = OUTPUT_DIR / "sample_people_cleaned.csv"
CHANGES = OUTPUT_DIR / "changes.csv"

EXPECTED_FIELDS = ["row_id", "name", "email", "department", "hours"]
DEPARTMENT_MAP = {
    "sales": "Sales",
    "engineering": "Engineering",
}


def clean_hours(value):
    trimmed = value.strip()
    if trimmed == "NA":
        return "", "NA converted to blank"
    if trimmed == "":
        return "", "trim whitespace"

    try:
        number = Decimal(trimmed)
    except InvalidOperation:
        return trimmed, "trim whitespace"

    if number == number.to_integral():
        normalized = str(number.quantize(Decimal("1")))
    else:
        normalized = format(number.normalize(), "f")
    return normalized, "normalize numeric notation"


def clean_cell(column, value):
    if column == "row_id":
        return value, "preserve row_id"

    if column == "name":
        return value.strip(), "trim name whitespace"

    if column == "email":
        trimmed = value.strip()
        return trimmed.lower() if trimmed else "", "trim and lowercase email"

    if column == "department":
        trimmed = value.strip()
        normalized = DEPARTMENT_MAP.get(trimmed.lower(), trimmed)
        return normalized, "trim and normalize known department"

    if column == "hours":
        return clean_hours(value)

    return value, "no rule"


def main():
    if not INPUT.is_file():
        sys.exit(f"Input file not found: {INPUT}")

    if OUTPUT_DIR.exists():
        sys.exit(f"Stop: {OUTPUT_DIR} already exists. Review or rename it first.")

    OUTPUT_DIR.mkdir()

    cleaned_rows = []
    changes = []

    with INPUT.open("r", encoding="utf-8", newline="") as source:
        reader = csv.DictReader(source)
        if reader.fieldnames != EXPECTED_FIELDS:
            sys.exit(
                f"Unexpected columns. Expected {EXPECTED_FIELDS}, got {reader.fieldnames}"
            )

        for row in reader:
            cleaned = {}
            for column in EXPECTED_FIELDS:
                before = row[column]
                after, rule = clean_cell(column, before)
                cleaned[column] = after

                if before != after:
                    changes.append(
                        {
                            "row_id": row["row_id"],
                            "column": column,
                            "before": before,
                            "after": after,
                            "rule": rule,
                        }
                    )

            cleaned_rows.append(cleaned)

    with CLEANED.open("x", encoding="utf-8", newline="") as target:
        writer = csv.DictWriter(target, fieldnames=EXPECTED_FIELDS)
        writer.writeheader()
        writer.writerows(cleaned_rows)

    with CHANGES.open("x", encoding="utf-8", newline="") as target:
        writer = csv.DictWriter(
            target,
            fieldnames=["row_id", "column", "before", "after", "rule"],
        )
        writer.writeheader()
        writer.writerows(changes)

    print(f"Rows written: {len(cleaned_rows)}")
    print(f"Changed cells: {len(changes)}")
    print(f"Cleaned copy: {CLEANED}")
    print(f"Change log: {CHANGES}")


if __name__ == "__main__":
    main()

Coloque clean_csv.py e sample_people.csv na mesma pasta e execute python clean_csv.py. Para este exemplo, o resumo esperado é 5 rows written e 9 changed cells.

06Revise cada célula alterada

Abra outputs/changes.csv antes de considerar o arquivo limpo pronto para uso. Cada linha deve explicar uma transformação usando row_id, coluna, valor original, valor novo e a regra que causou a mudança.

  1. Confirme que o registro de alterações contém exatamente 9 linhas neste exemplo sintético.
  2. Verifique se os próprios valores de row_id nunca aparecem como células alteradas.
  3. Compare as 9 entradas com a tabela calculada manualmente acima.
  4. Confirme que row 2 não aparece no registro de alterações.
  5. Abra outputs/sample_people_cleaned.csv e confirme que ele ainda contém 5 linhas de dados na ordem original.
  6. Investigue qualquer alteração adicional em vez de presumir que a regra sugerida pela IA estava correta.

07Erros comuns e limites

  • Não peça à IA para inferir valores ausentes de hours, department ou email, a menos que exista um método separado e justificável para isso.
  • Evite transformações amplas de texto, como converter todos os nomes para Title Case, sem verificar se valores legítimos seriam alterados.
  • Não exclua duplicatas apenas porque duas linhas parecem semelhantes. Deduplicação exige uma regra explícita de correspondência de registros.
  • Não sobrescreva o CSV original. Preserve tanto a entrada intacta quanto a saída revisada.
  • Não revise apenas um total como 9 changes. Verifique quais células mudaram e por quê.
  • Em conjuntos de dados grandes ou sensíveis, teste primeiro as regras em uma amostra representativa e adicione validações específicas do domínio antes de aplicá-las em larga escala.

Aqui, a IA é útil como assistente para redigir regras, não como autoridade final sobre o significado dos dados. Definições de colunas, categorias válidas, convenções de valores ausentes e transformações aceitáveis devem vir do responsável pelo conjunto de dados ou de outra fonte confiável.

Registro de execução e verificação

ChatGPT Python tool · Python 3.x · standard library csv, sys, decimal, pathlib

  • A primeira execução foi concluída com sucesso.
  • A saída do console correspondeu exatamente ao artigo: 5 rows written e 9 changed cells.
  • O log de alterações continha exatamente 9 mudanças: 3 em row 1, 3 em row 3, 2 em row 4 e 1 em row 5.
  • As nove mudanças corresponderam exatamente à tabela prevista: row 1 name/email/department; row 3 email/department/hours; row 4 department/hours; row 5 department.
  • Row 2 não apareceu no log de alterações.
  • O CSV limpo manteve todas as 5 linhas na ordem original e preservou todos os row_id.
  • Os valores limpos ficaram como esperado, incluindo 8.0 -> 8, NA -> blank, normalização de department, remoção de espaços em branco e conversão para minúsculas dos endereços email não vazios.
  • sample_people.csv permaneceu idêntico byte por byte após a execução.
  • Uma segunda execução foi interrompida com 'Stop: outputs already exists. Review or rename it first.' e não sobrescreveu as saídas anteriores.
Limites da verificação
  • O teste cobre apenas o CSV sintético fornecido e as regras aprovadas; ele não valida mapeamentos mais amplos de department, entrada CSV malformada, codificações incomuns, campos multilinha nem regras de dados específicas de domínio.
  • O ambiente Python emitiu no stderr um aviso não relacionado de aquecimento do ambiente de planilhas; isso não afetou o script do artigo nem seus resultados.

Fontes de referência

As explicações e os exemplos são de elaboração própria. Os comportamentos e conceitos relacionados podem ser consultados nas fontes oficiais abaixo.