# Data Cleaner

> Agent expert en nettoyage, normalisation et structuration de données brutes. Spécialisé PostgreSQL, pandas, SQL batch, déduplication, validation Zod/Pydantic. Use when: nettoyer des données, dédupliquer, normaliser, standardiser des formats, corriger des incohérences, valider la qualité, structurer du JSON/CSV brut, mapper des référentiels (NAF, INSEE, région→département), détecter des anomalies. Triggers: nettoyage, data quality, déduplication, normalisation, ETL, mapping, standardisation, anomalie, incohérence, données sales, import CSV, structuration.

- Skill: `thewatcher01/data-cleaner` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add thewatcher01/data-cleaner`
- Raw SKILL.md: https://api.skillmd.com/api/skills/thewatcher01/data-cleaner/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Data & Analytics
- Author: TheWatcher01 (https://skillmd.com/u/thewatcher01)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/thewatcher01/data-cleaner

---


# Data Cleaner Agent — Nettoyage & Structuration

## Principes fondamentaux

1. **Jamais modifier en place** — créer colonne/table temporaire, valider, puis remplacer
2. **Idempotent** — chaque opération relançable sans effet de bord
3. **Traçable** — loguer chaque transformation (avant/après, nb lignes)
4. **Batch first** — jamais de row-by-row, toujours UPDATE ... FROM ou COPY
5. **Valider avant d'écrire** — Zod (TS) ou Pydantic (Python) sur chaque output

## Workflow en 6 étapes

### 1. Audit de qualité (diagnostic)

Avant toute action, mesurer l'état actuel. Voir `references/audit-template.md`.

### 2. Déduplication

Ordre de priorité :
1. Doublons exacts — GROUP BY toutes colonnes, garder min(id)
2. Doublons sémantiques — normaliser puis dédupliquer ("Assoc." = "Association")
3. Doublons fuzzy — pg_trgm similarity seuil 0.8

```sql
DELETE FROM table a USING table b
WHERE a.col1 = b.col1 AND a.col2 = b.col2 AND a.id > b.id;
```

### 3. Normalisation textuelle

Appliquer dans cet ordre :
1. `trim(both from col)`
2. `regexp_replace(col, '\s+', ' ', 'g')` (collapse spaces)
3. NFD unicode normalization (pour index de recherche)
4. `upper()` pour codes, `initcap()` pour noms propres
5. `regexp_replace(col, '[\x00-\x1F]', '', 'g')` (caractères de contrôle)

### 4. Mapping référentiels

Toujours via tables de mapping statiques. Voir `references/referentiels.md`.

### 5. Validation des formats

| Champ | Pattern | Exemple |
|-------|---------|---------|
| SIREN | `^\d{9}$` | 813065398 |
| SIRET | `^\d{14}$` | 81306539800016 |
| RNA | `^W\d{9}$` | W831003504 |
| NAF | `^\d{2}\.\d{2}[A-Z]$` | 88.99B |
| Code postal | `^\d{5}$` | 83300 |
| Email | `^[^\s@]+@[^\s@]+\.[^\s@]+$` | - |

```sql
-- Identifier invalides AVANT correction
SELECT siren, count(*) FROM table WHERE siren !~ '^\d{9}$' GROUP BY siren;
```

### 6. Enrichissement croisé

Après nettoyage, croiser les sources pour combler les trous. Voir `references/enrichissement.md`.

## Anti-patterns

- UPDATE sans WHERE
- DELETE sans backup (`CREATE TABLE backup AS SELECT * FROM ...`)
- Regex trop permissives — valider sur échantillon 100 lignes
- Normalisation destructive — garder colonne originale, créer colonne `_clean`
- Import sans staging table temporaire

## Métriques à reporter

```
[CLEAN] table.col : X lignes modifiées / Y total (Z%)
[DEDUP] table : X doublons supprimés (Y restants)
[VALID] table.col : X invalides (patterns: ...)
[ENRICH] table.col : X valeurs comblées depuis source Y
```

## Libs déterministes (pallier l'imprévisibilité LLM)

Toujours préférer un script déterministe à une réponse LLM pour les transformations de données.

### Validation (exécuter `scripts/validate_column.py`)

```bash
# Valider SIREN
python3 scripts/validate_column.py dl_entities siren --type siren

# Valider avec regex custom
python3 scripts/validate_column.py dl_entities "nafCode" --pattern '^\d{2}\.\d{2}[A-Z]$'
```

### Python — libs fiables (pip install)

| Lib | Usage | Pourquoi |
|-----|-------|----------|
| `ftfy` | Fix encoding (mojibake, BOM) | Déterministe, gère 99% des cas d'encoding |
| `unidecode` | Translittération unicode → ASCII | Pour les index de recherche sans accents |
| `phonetics` | Soundex/Metaphone noms propres | Matching fuzzy déterministe (pas de LLM) |
| `pandas` | Batch transforms DataFrame | Vectorisé, 100x plus rapide que row-by-row |
| `great_expectations` | Data quality assertions | Pipeline de validation reproductible |
| `pydantic` | Schema validation Python | Rejet strict des données non conformes |
| `email-validator` | Validation email RFC 5321 | Plus fiable que regex |
| `stdnum` | Validation SIREN/SIRET/TVA | Lib officielle, checksums inclus |

### TypeScript — libs fiables (pnpm add)

| Lib | Usage |
|-----|-------|
| `zod` | Schema validation (déjà installé) |
| `validator` | isEmail, isSIRET, isPostalCode... |

### PostgreSQL — extensions utiles

| Extension | Usage |
|-----------|-------|
| `pg_trgm` | Fuzzy matching trigram (similarity > 0.8) |
| `unaccent` | Recherche sans diacritiques |
| `fuzzystrmatch` | Levenshtein, Soundex, Metaphone |

### Pattern : script > LLM

Pour chaque opération de nettoyage, l'agent doit :
1. Écrire un script Python/SQL déterministe
2. Le tester sur un échantillon (LIMIT 100)
3. Vérifier le résultat avec `validate_column.py`
4. Appliquer en batch sur la table complète
5. Reporter les métriques [CLEAN] [DEDUP] [VALID] [ENRICH]

Ne jamais laisser le LLM "deviner" une transformation — toujours coder un script reproductible.

