Pandas & NumPy Academy · Leçon

Configuration du projet et ingestion des données

Définissez les objectifs du projet, chargez les données depuis un CSV et une base SQLite, fusionnez les sources et effectuez un audit complet de l’ensemble de données combiné.

Leçon 1 sur 413 étapes

Configuration du projet et ingestion des données est une leçon Pandas & NumPy Academy gratuite sur CoddyKit. Ceci est la leçon 1 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage Pandas & NumPy Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours Pandas & NumPy Academy comprend 4 leçons au total.

Objectif du projet de synthèse

Dans ce projet de synthèse, vous réunirez toutes les compétences acquises pendant le cours — NumPy, Pandas, visualisation, tests statistiques, connexion à une base de données et conception d’un pipeline — au sein d’un flux de travail unique de bout en bout. Le projet simule une tâche réelle d’analyste : importer des données brutes provenant de deux sources (un fichier CSV et une table de base de données), les fusionner, contrôler leur qualité, calculer des KPI avancés, visualiser les tendances et exporter un rapport soigné. Cela correspond au travail quotidien des analystes de données professionnels dans le secteur.

Définir les objectifs du projet et les KPI

Avant d’écrire la moindre ligne de code, définissez les objectifs de votre projet et les indicateurs clés de performance (KPI) que vous allez calculer. Documentez les éléments suivants : à quelle question métier répondez-vous ? De quelles sources de données disposez-vous ? Quels formats de sortie sont nécessaires ? Pour ce projet de synthèse : analysez les tendances mensuelles du chiffre d’affaires par catégorie de produit, calculez la rétention par cohorte, identifiez les principales régions selon la marge bénéficiaire et exportez un rapport avec des visualisations. Un objectif clair évite l’élargissement incontrôlé du périmètre et permet de garder le pipeline ciblé.

# Project configuration — define goals upfront
CONFIG = {
    'csv_path': 'data/orders_2024.csv',
    'db_url': 'sqlite:///customer_db.sqlite',
    'db_table': 'customers',
    'output_dir': 'output/',
    'report_path': 'output/report.md',
    'analysis_year': 2024,
    'top_n_regions': 5,
    'rolling_window_days': 30
}

print('Project config loaded.')
print('Target KPIs: monthly revenue, cohort retention, top regions by margin')

Charger des données depuis un fichier CSV

Chargez le fichier CSV en indiquant explicitement les arguments dtype et parse_dates afin d’éviter les erreurs d’inférence. Dans un projet réel, le fichier CSV peut avoir été exporté par un autre système appliquant des conventions différentes — définissez si nécessaire encoding, sep et thousands. Vérifiez immédiatement shape, dtypes et head() pour confirmer que le chargement s’est correctement déroulé avant toute transformation. Cette première inspection révèle souvent des problèmes d’encodage, des lignes d’en-tête supplémentaires ou des noms de colonnes inattendus.

import pandas as pd

df_orders = pd.read_csv(
    'data/orders_2024.csv',
    dtype={
        'order_id': 'int32',
        'customer_id': 'int32',
        'product_id': 'int32',
        'quantity': 'int16',
        'unit_price': 'float32',
        'region': 'category',
        'category': 'category'
    },
    parse_dates=['order_date'],
    encoding='utf-8'
)
print(f'Orders loaded: {df_orders.shape}')
print(df_orders.dtypes)
print(df_orders.head(3))

Charger des données depuis la base de données

La deuxième source de données est la table des clients dans une base de données SQLite. Chargez uniquement les colonnes nécessaires à l’analyse à l’aide d’un SELECT SQL, plutôt que la table entière. Reliez les deux sources à l’aide de customer_id afin d’enrichir chaque commande avec les données démographiques du client. Avant la fusion, vérifiez que les clés customer_id sont du même type dans les deux sources — une cause fréquente d’échecs silencieux de fusion consiste à comparer une clé int32 à une clé de type chaîne.

import pandas as pd
import sqlalchemy as sa

engine = sa.create_engine('sqlite:///customer_db.sqlite')

df_customers = pd.read_sql_query(
    '''
    SELECT customer_id, customer_name, country,
           acquisition_channel, signup_date
    FROM customers
    ''',
    con=engine,
    dtype={'customer_id': 'int32'},
    parse_dates=['signup_date']
)
print(f'Customers loaded: {df_customers.shape}')
print(df_customers.dtypes)
print(df_customers.head(3))

Fusionner les deux sources

Fusionnez les commandes avec les clients sur customer_id en utilisant une jointure gauche, afin de conserver toutes les commandes même si une fiche client est manquante. Après la fusion, vérifiez combien de commandes n’ont aucun client correspondant (customer_name.isna().sum()) — il s’agit d’un indicateur de qualité des données qui mérite d’être étudié. Examinez la forme du DataFrame obtenu pour confirmer que la fusion n’a pas dupliqué ni supprimé de lignes de manière inattendue. Documentez la logique de fusion dans un commentaire à l’intention des personnes qui assureront la maintenance ultérieure.

import pandas as pd

# Left join: keep all orders, enrich with customer data where available
df = pd.merge(
    df_orders,
    df_customers,
    on='customer_id',
    how='left'
)

print(f'Orders: {len(df_orders)}, Customers: {len(df_customers)}')
print(f'Merged: {df.shape}')
unmatched = df['customer_name'].isna().sum()
print(f'Orders with no matching customer: {unmatched} ({unmatched/len(df):.1%})')

Liste complète de contrôle de l’audit des données

Après le chargement et la fusion, effectuez un audit systématique des données avant toute analyse. Vérifiez : le nombre total de lignes et de colonnes, les valeurs manquantes par colonne (en pourcentage), les types de données de toutes les colonnes, les identifiants de commande en double, la couverture de la période, les valeurs négatives dans les colonnes numériques et la cardinalité des colonnes catégorielles. Documentez vos constats dans un résumé textuel. Détecter ici les problèmes de qualité des données évite des erreurs silencieuses dans les calculs ultérieurs des KPI.

import pandas as pd

def audit_dataframe(df, name='DataFrame'):
    print(f'=== Audit: {name} ===')
    print(f'Shape: {df.shape}')
    print(f'Date range: {df["order_date"].min()} to {df["order_date"].max()}')
    print(f'Duplicate order_ids: {df["order_id"].duplicated().sum()}')
    print('Missing values:')
    missing = df.isnull().sum()
    print(missing[missing > 0].to_string())
    print('Negative quantities:', (df['quantity'] < 0).sum())
    print('Negative prices:', (df['unit_price'] < 0).sum())
    print()

audit_dataframe(df, 'Merged Orders + Customers')

Corriger les anomalies d’analyse des dates

Les colonnes de dates issues d’exportations CSV présentent souvent des cas particuliers : des dates futures qui ne devraient pas exister, des dates d’une mauvaise année (erreur courante de saisie) ou des dates manquantes pour les commandes annulées. Après avoir analysé les dates, validez la plage attendue et remplacez les valeurs situées hors de cette plage par NaT. Vérifiez également les commandes pour lesquelles order_date < customer signup_date — il s’agit d’événements impossibles qui signalent des problèmes de qualité des données à mentionner dans le rapport d’audit.

import pandas as pd
from datetime import datetime

# Flag impossible dates
df['date_valid'] = (
    (df['order_date'] >= '2024-01-01') &
    (df['order_date'] <= datetime.now())
)
print('Invalid order dates:', (~df['date_valid']).sum())

# Flag orders before customer signup
df['signup_date'] = pd.to_datetime(df['signup_date'])
df['date_before_signup'] = df['order_date'] < df['signup_date']
print('Orders before customer signup:', df['date_before_signup'].sum())

# Set invalid dates to NaT
df.loc[~df['date_valid'], 'order_date'] = pd.NaT

Gérer les quantités négatives et les retours

Dans une table de commandes, les quantités négatives représentent généralement des retours ou des remboursements. Au lieu de les supprimer simplement, séparez-les en deux DataFrames : les commandes positives et les retours. Vous pourrez ainsi calculer séparément le chiffre d’affaires brut (commandes positives uniquement) et le chiffre d’affaires net (valeurs positives + négatives), ce qui donnera une image plus fidèle de l’activité. Ajoutez à chaque ligne une colonne booléenne is_return et conservez les deux types dans le DataFrame fusionné à des fins d’audit.

import pandas as pd

# Tag returns
df['is_return'] = df['quantity'] < 0

returns = df[df['is_return']]
orders = df[~df['is_return']]

print(f'Normal orders: {len(orders)}')
print(f'Returns/refunds: {len(returns)} ({len(returns)/len(df):.1%})')
print(f'Return rate by category:')
print(
    df.groupby('category')['is_return']
    .mean()
    .sort_values(ascending=False)
    .round(3)
)

Vérifier l’exhaustivité de la jointure

Après une jointure gauche, vérifiez que celle-ci est complète comme prévu. Comptez le nombre de valeurs uniques de customer_id présentes dans les commandes mais absentes de la table des clients. Il s’agit d’enregistrements orphelins — des clients qui ont passé des commandes mais ne possèdent aucune fiche client. Ils peuvent correspondre à des comptes supprimés, à des achats en tant qu’invité ou à une interruption dans le pipeline de données. Documentez ce nombre et décidez s’il faut les exclure de l’analyse de rétention tout en les incluant dans les totaux de chiffre d’affaires.

import pandas as pd

order_customers = set(df_orders['customer_id'].unique())
customer_ids = set(df_customers['customer_id'].unique())

orphans = order_customers - customer_ids
print(f'Customer IDs in orders not in customer table: {len(orphans)}')
print(f'Coverage: {len(order_customers & customer_ids) / len(order_customers):.1%} of order customers have records')

# Revenue from unmatched customers
orphan_revenue = df[df['customer_id'].isin(orphans)]['unit_price'].sum()
print(f'Revenue from orphan customers: ${orphan_revenue:,.0f}')

Enregistrer le jeu de données audité

Après l’audit, enregistrez le jeu de données nettoyé et fusionné au format Parquet afin que les étapes suivantes du pipeline (création de variables, calcul des KPI, visualisation) puissent le recharger instantanément sans répéter les opérations de fusion et d’analyse des dates. Écrivez des fichiers distincts pour les commandes propres et le DataFrame des retours. Ce fonctionnement par points de contrôle rend le pipeline reprenable et vous permet de déboguer les étapes ultérieures sans relancer l’importation.

import os
import pandas as pd

OS_DIR = 'output/'
os.makedirs(OS_DIR, exist_ok=True)

# Save clean orders (excluding returns and invalid dates)
clean_orders = df[
    (~df['is_return']) &
    df['order_date'].notna()
].copy()

clean_orders.to_parquet(OS_DIR + 'clean_orders.parquet', index=False)
df[df['is_return']].to_parquet(OS_DIR + 'returns.parquet', index=False)

print(f'Clean orders saved: {len(clean_orders):,} rows')
print(f'Returns saved: {len(df[df["is_return"]]):,} rows')
print(f'Files in {OS_DIR}: {os.listdir(OS_DIR)}')

Rapport récapitulatif de l’audit

La dernière étape de l’ingestion des données consiste à rédiger un bref résumé d’audit qui consigne vos constatations. Il peut s’agir d’un journal affiché ou d’un fichier Markdown. Incluez : le nombre de lignes chargées depuis chaque source, le taux de correspondance lors de la fusion, la plage de dates, le pourcentage de valeurs manquantes, le nombre de retours trouvés et toute anomalie. Le résumé d’audit fait partie du livrable final et aide les parties prenantes à avoir confiance dans le nettoyage correct des données avant l’analyse.

import pandas as pd
from datetime import datetime

def write_audit_summary(df, path):
    lines = [
        '# Data Ingestion Audit',
        f'Generated: {datetime.now().strftime("%Y-%m-%d %H:%M")}',
        '',
        f'- Total records after merge: {len(df):,}',
        f'- Clean orders: {(~df["is_return"]).sum():,}',
        f'- Returns: {df["is_return"].sum():,}',
        f'- Date range: {df["order_date"].min().date()} to {df["order_date"].max().date()}',
        f'- Unique customers: {df["customer_id"].nunique():,}',
        f'- Unique categories: {df["category"].nunique()}',
        f'- Missing unit_price: {df["unit_price"].isna().sum()}'
    ]
    with open(path, 'w') as f:
        f.write('\n'.join(lines))

write_audit_summary(df, 'output/audit.md')
print('Audit summary written.')

Vérification rapide

Vérifiez votre compréhension des concepts d’analyse de données présentés dans cette leçon.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris que la définition préalable des objectifs et de la configuration permet de garder le pipeline ciblé et facile à maintenir, que les arguments explicites dtype et parse_dates dans read_csv empêchent les erreurs de type silencieuses, et qu’une liste de contrôle systématique de l’audit des données (doublons, valeurs manquantes, dates impossibles, quantités négatives) détecte les problèmes de qualité avant qu’ils ne faussent les calculs des KPI. Nous allons maintenant nettoyer les données et créer des caractéristiques pour l’analyse.

Gratuit pour commencer

Apprends Python avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
30
Leçons
120

Questions Fréquemment Posées

La leçon « Configuration du projet et ingestion des données » est-elle gratuite ?

Oui — le texte complet de « Configuration du projet et ingestion des données » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours Pandas & NumPy Academy, passe à CoddyKit PRO. Le cours Pandas & NumPy Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Configuration du projet et ingestion des données » ?

Définissez les objectifs du projet, chargez les données depuis un CSV et une base SQLite, fusionnez les sources et effectuez un audit complet de l’ensemble de données combiné. Tu pratiques Pandas & NumPy Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer Pandas & NumPy Academy ?

Aucune expérience préalable n'est requise. Pandas & NumPy Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 1 sur 4.

Combien de temps prend la leçon « Configuration du projet et ingestion des données » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon Pandas & NumPy Academy ?

Oui. Chaque leçon Pandas & NumPy Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Configuration du projet et ingestion des données
  2. Nettoyage des données et ingénierie des caractéristiques
  3. Analyse et calcul des KPI
  4. Visualisation finale et export du rapport
← Retour à Pandas & NumPy Academy