Entre dépendance à l'import et montée en puissance à l'export
Projet de fin d'études — Formation Data Analyst, Simplon Maghreb × Jobintech Réalisé par Hamza Khiar
Le secteur automobile est l'un des piliers de l'économie marocaine, entre usines de montage (Renault, Stellantis) et un réseau dense d'équipementiers. Ce projet analyse le commerce extérieur du Maroc sur le Chapitre SH 87 (véhicules, pièces et accessoires) sur la période 2022–2025, à partir des données officielles de l'Office des Changes.
L'objectif est de répondre à une question simple mais structurante pour le secteur : le Maroc reste-t-il dépendant de l'import de véhicules, ou sa montée en puissance à l'export (véhicules finis, pièces) est-elle en train de rééquilibrer sa balance commerciale ?
Comment évolue la balance commerciale du secteur véhicules au Maroc entre 2022 et 2025, et quels segments (véhicules finis vs pièces & accessoires) et marchés (pays/continents) expliquent cette évolution ?
| KPI | Description |
|---|---|
| Total Export / Total Import | Valeur DHS des flux d'exportation (FAB) et d'importation (CAF) |
| Balance Commerciale | Export − Import |
| % Couverture | Export / Import — capacité des exportations à couvrir les importations |
| DHS par KG | Densité économique d'un produit (valeur générée par kilo transporté) |
| Nombre de transactions | Volume d'opérations commerciales enregistrées |
| Nombre de pays partenaires | Diversité géographique des échanges |
| Répartition par catégorie de produit | Véhicule fini vs Pièces & Accessoires vs Autre |
Deux fichiers CSV distincts fournis par l'Office des Changes, couvrant les flux Import et Export du Chapitre SH 87 sur 2022–2025 :
Import.csvExport.csv
Chaque ligne représente une transaction commerciale avec : produit (code/libellé SH), groupement d'utilisation, classification CTCI, pays et continent partenaires, flux (import/export), année, mois, poids (kg), valeur (DHS) et unité complémentaire.
Import.csv + Export.csv
│
▼
Python / pandas → Nettoyage, typage, EDA, tests statistiques
│
▼
SQL Server (SSMS, SQLEXPRESS)
staging.commerce_transaction → Modélisation en étoile (schéma prod)
│
▼
Power BI → Dashboard interactif (DirectQuery)
- Lecture des deux CSV (séparateur
;, décimales,), suppression des colonnes redondantes (Code/Libellé du chapitre SH, puisque le chapitre 87 est fixe sur tout le dataset). - Vérification de la couverture temporelle (2022–2025) et contrôle de cardinalité colonne par colonne.
- Détection d'un cas de doublon apparent sur
Libellé du produit SH: en réalité pas une erreur de saisie mais la coexistence de codes SH globaux et de codes SH localisés marocains (6 codes génériques vs +4 codes spécifiques) — décision de conserver les deux niveaux de granularité plutôt que de les fusionner et perdre de l'information. - Détection et suppression d'une anomalie : des lignes avec un poids de 0 kg mais une valeur DHS positive, qui faussaient le calcul de densité économique (DHS/kg).
- Ajout d'une colonne dérivée
Categorie Produit(Véhicule Fini / Pièces & Accessoires / Autre) basée sur le préfixe du code SH, utilisée pour les analyses croisées import/export. - Exploration statistique complète : top produits par valeur et par volume, densité économique (DHS/kg), répartition par groupement d'utilisation, concentration des exports par pays, saisonnalité des imports.
- Tests d'hypothèses menés pour valider les observations : Chi² (dépendance pays × année sur le nombre de transactions), t-test de Student/Welch (après test de Levene) sur la densité DHS/kg entre catégories de produits, corrélation de Pearson (poids vs valeur à l'import), ANOVA (valeur DHS par mois à l'import).
- Concaténation finale des deux dataframes en un seul jeu de données prêt pour le chargement.
Chargement initial dans staging.commerce_transaction (~74 853 lignes) via pandas.to_sql(), puis modélisation en étoile en T-SQL dans le schéma prod :
dimProduit— code et libellé du produit SHdimGroupement— hiérarchie officielle Office des Changes (groupement d'utilisation)dimCTCI— classification section / division / groupe CTCIdimPays— pays et continentFact_Commerce— table de faits (flux, année, mois, poids, valeur, unité complémentaire), avec clés étrangères vers chaque dimension
Deux bugs rencontrés et corrigés pendant cette étape :
- Performance —
to_sql()crée par défaut des colonnes texte enVARCHAR(MAX), ce qui rendait lesSELECT DISTINCT/ORDER BYextrêmement lents (jusqu'à 1 min 43). Résolu en recalculant les longueurs réelles nécessaires (MAX(LEN(...))) et en redimensionnant les colonnes viaALTER TABLE ... ALTER COLUMN, avec undtype_mapperexplicite côté Python pour éviter le problème sur les futurs chargements. - Intégrité des données —
dimPaysétait initialement clé surCode du pays. La Namibie avait un code pays NULL malgré un libellé valide, ce qui provoquait une perte silencieuse d'une ligne lors duINNER JOINvers la table de faits (74 853 lignes en staging vs 74 852 dans le fait). Corrigé en reclédimPayssurlibelle_pays(après vérification qu'aucun libellé n'était associé à deux codes ou continents différents), avec mise à jour du join correspondant.
Note : to_sql(if_exists="delete_rows") ne fait pas un TRUNCATE — il supprime ligne par ligne, à garder en tête pour les futures itérations du pipeline.
Point de conception encore ouvert : ajout d'une dimension DimPeriode/DimDate pour le time intelligence DAX, actuellement Année et Mois sont des colonnes brutes (BIGINT) dans la table de faits.
Connexion en DirectQuery (choix volontaire plutôt qu'Import) sur un dataset d'environ 80 000 lignes, pour documenter en conditions réelles les limites de ce mode : colonnes calculées limitées, time intelligence DAX contraint, gestion des relations bidirectionnelles plus délicate.
Mesures DAX principales :
Total Export = CALCULATE(
SUM('prod Fact_Commerce'[valeur_dhs]),
'prod Fact_Commerce'[libelle_flux] = "Exportations FAB"
)
Total Import = CALCULATE(
SUM('prod Fact_Commerce'[valeur_dhs]),
'prod Fact_Commerce'[libelle_flux] = "Importations CAF"
)
Balance Commerciale = [Total Export] - [Total Import]
% Couverture = DIVIDE([Total Export], [Total Import])
DHS per KG = DIVIDE(SUM('prod Fact_Commerce'[valeur_dhs]), SUM('prod Fact_Commerce'[poids_kg]))
Qté Valeur DHS Mesure =
VAR selected_Value = SELECTEDVALUE('Qté et Valeur DHS'[Parameter Order])
RETURN SWITCH(
selected_Value,
0, SUM('prod Fact_Commerce'[valeur_dhs]),
1, COUNT('prod Fact_Commerce'[id_produit]),
BLANK()
)
Page de garde
Modèle de données Power BI
Page 1 — Analyse des flux commerciaux (Import / Export)
Page 2 — Balance commerciale et performance du secteur
- Sur la période, le Maroc affiche une balance commerciale positive (~20 milliards DHS) sur le secteur véhicules, avec un taux de couverture proche ou supérieur à 100% jusqu'en 2024.
- Le taux de couverture se dégrade en 2025 (sous 90%), signe d'un rééquilibrage récent en faveur de l'import.
- Les véhicules finis dominent largement les exportations (~92–93% de la valeur), loin devant les pièces & accessoires.
- La concentration géographique des exportations sur les trois premiers pays clients diminue d'année en année — une diversification progressive plutôt qu'une dépendance à quelques marchés.
- La France reste le premier partenaire commercial en valeur.
- Extraction & analyse : Python (pandas, NumPy, SciPy, Matplotlib, Seaborn)
- Stockage & modélisation : SQL Server (SSMS, instance locale SQLEXPRESS), T-SQL
- Visualisation : Power BI, DAX, DirectQuery
- Gestion de projet : suivi des tâches et jalons via outil de gestion de projet dédié
- Placer
Import.csvetExport.csvdans./. - Exécuter
main.pypour le nettoyage et l'EDA. - Charger le dataframe final dans
staging.commerce_transactionsur une instance SQL Server. - Exécuter
sql_query_transofrmation.sqlpour créer le schémaprodet peupler les dimensions et la table de faits. - Ouvrir
dashboard.pbixet connecter la source SQL Server en DirectQuery.
- Automatisation du rafraîchissement des données (script planifié ou Airflow)
- Test comparatif DirectQuery vs Import mode sur les temps de réponse du dashboard



