Les données footballistiques représentent une source précieuse pour analyser les performances des équipes, identifier les tendances saisonnières et soutenir la prise de décision dans le sport.
Ce projet a pour objectif de construire un pipeline PySpark complet permettant d’analyser la performance des équipes saison par saison, de calculer des indicateurs clés de performance (KPI), de classer les équipes, et de stocker les résultats au format Parquet partitionné.
- Charger et préparer les données de matchs de football.
- Calculer des statistiques avancées par équipe et par saison.
- Identifier les champions de chaque saison.
- Sauvegarder les résultats sous format Parquet partitionné par saison.
- Visualiser les performances des équipes gagnantes.
- (Bonus) Intégrer le pipeline dans Databricks et créer un dashboard Power BI.
| Rôle | Besoin | Résultat attendu |
|---|---|---|
| Analyste | Visualiser un tableau clair des performances par équipe et par saison. | Table des KPI par saison. |
| Supporter | Connaître les champions de chaque saison. | Tableau ou graphique des équipes championnes. |
| Manager sportif | Disposer d’indicateurs (% victoires, buts marqués, goal diff) pour orienter la stratégie. | Dashboard Power BI ou graphiques. |
flowchart TB
%% =====================================================
%% ARCHITECTURE DU PIPELINE ANALYTIQUE FOOTBALL (BUNDESLIGA)
%% =====================================================
%% === STYLES PROFESSIONNELS ===
classDef ingest fill:#E3F2FD,stroke:#1E88E5,stroke-width:2px,color:#0D47A1,font-weight:bold
classDef transform fill:#E8F5E9,stroke:#43A047,stroke-width:2px,color:#1B5E20,font-weight:bold
classDef compute fill:#FFF3E0,stroke:#FB8C00,stroke-width:2px,color:#E65100,font-weight:bold
classDef analytics fill:#FCE4EC,stroke:#D81B60,stroke-width:2px,color:#880E4F,font-weight:bold
classDef persist fill:#FFFDE7,stroke:#F9A825,stroke-width:2px,color:#827717,font-weight:bold
classDef visualize fill:#E0F2F1,stroke:#00897B,stroke-width:2px,color:#004D40,font-weight:bold
%% === 1. DATA INGESTION ===
subgraph INGESTION["1. Data Ingestion & Preparation"]
I1["Load CSV files into PySpark DataFrames"]
I2["Data Cleaning & Column Normalization"]
I3["Feature Engineering\n(HomeWin, AwayWin, Draw)"]
end
class I1,I2,I3 ingest
%% === 2. DATA FILTERING ===
subgraph FILTERING["2. Data Filtering"]
F1["League Selection\n(Bundesliga – Div = D1)"]
F2["Season Range Filter\n(2000 – 2015)"]
end
class F1,F2 transform
%% === 3. DATA AGGREGATION ===
subgraph AGGREGATION["3. Aggregation Layer"]
A1["Home Matches Statistics"]
A2["Away Matches Statistics"]
A3["Merge Home & Away Metrics"]
end
class A1,A2,A3 compute
%% === 4. KPI COMPUTATION ===
subgraph KPI["4. KPI Computation"]
K1["Basic KPIs\n(Goals, Wins, Losses, Draws)"]
K2["Advanced KPIs\n(Win %, Goal Difference,\nGoals per Match)"]
end
class K1,K2 analytics
%% === 5. TEAM RANKING ===
subgraph RANKING["5. Team Ranking"]
R1["Window Functions\nRanking by Performance"]
R2["Champion Selection\n(Rank = 1)"]
end
class R1,R2 analytics
%% === 6. DATA PERSISTENCE ===
subgraph STORAGE["6. Data Persistence"]
S1["Partitioned Dataset\n(All Teams by Season)"]
S2["Final Dataset\n(Champions Only)"]
end
class S1,S2 persist
%% === 7. VISUALIZATION & REPORTING ===
subgraph VISUAL["7. Visualization & Reporting"]
V1["Win Percentage Analysis"]
V2["Goals Scored Trends"]
V3["Goal Difference Evolution"]
V4["BI & Analytics Tools\n(Pandas, Matplotlib, Power BI)"]
end
class V1,V2,V3,V4 visualize
%% === PIPELINE FLOW ===
I1 --> I2 --> I3
I3 --> F1 --> F2
F2 --> A1 --> A2 --> A3
A3 --> K1 --> K2
K2 --> R1 --> R2
R2 --> S1 --> S2
S2 --> V1 --> V4
S2 --> V2 --> V4
S2 --> V3 --> V4
-
Chargement et préparation des données
- Import du fichier CSV dans un DataFrame PySpark.
- Nettoyage et renommage des colonnes selon
footballcolumnsdocumentation.pdf.
-
Création de colonnes supplémentaires
- Colonnes indicatrices :
HomeTeamWin,AwayTeamWin,GameTie.
- Colonnes indicatrices :
-
Filtrage des données
- Conservation uniquement de la Bundesliga (Div = D1).
- Période : 2000 à 2015.
-
Agrégations
df_home_matches: statistiques à domicile.df_away_matches: statistiques à l’extérieur.- Jointure →
df_merged.
-
Calcul des KPI
- Colonnes totales :
GoalsScored,GoalsAgainst,Win,Loss,Tie. - Colonnes avancées :
GoalDifferentials,WinPercentage,GoalsPerGame,GoalsAgainstPerGame.
- Colonnes totales :
-
Classement des équipes
- Utilisation des Window Functions pour classer les équipes selon :
WinPercentageGoalDifferentials
- Extraction du champion :
TeamPosition = 1.
- Utilisation des Window Functions pour classer les équipes selon :
-
Sauvegarde optimisée
football_stats_partitioned: toutes les équipes, partitionné par saison.football_top_teams: champions uniquement.
-
Visualisation (Pandas / Matplotlib / Power BI)
- Graphiques :
- % de victoires des champions.
- Nombre de buts marqués.
- GoalDifferentials par saison.
- Graphiques :
football-performance-pipeline/
│
├── data/
│ ├── raw/ # Données CSV brutes
│ │ └── football_matches.csv
│ ├── processed/ # Données transformées (parquet)
│ │ ├── football_stats_partitioned/
│ │ └── football_top_teams/
│ └── tests/ # Jeux de données miniatures pour tests
│ └── sample_data.csv
│
├── src/
│ ├── __init__.py
│ ├── config/
│ │ └── spark_config.py # Configuration SparkSession
│ ├── ingestion/
│ │ └── load_data.py # Chargement CSV → DataFrame
│ ├── transformation/
│ │ ├── prepare_columns.py # Nettoyage, renommage
│ │ ├── indicators.py # Colonnes indicatrices (HomeTeamWin, etc.)
│ │ ├── filter_data.py # Filtrage D1 + saisons 2000–2015
│ │ ├── aggregations.py # GroupBy domicile / extérieur
│ │ ├── merge_data.py # Fusion home/away
│ │ ├── metrics.py # Colonnes synthétiques + KPIs
│ │ └── ranking.py # Classement via Window Functions
│ ├── export/
│ │ └── save_parquet.py # Sauvegarde des Parquet
│ ├── visualization/
│ │ └── charts.py # Graphiques Matplotlib / Seaborn
│ └── pipeline.py # Script principal orchestrant le pipeline
│
├── tests/
│ ├── __init__.py
│ ├── test_ingestion.py # Tests du chargement
│ ├── test_transformation.py # Tests transformations & indicateurs
│ ├── test_metrics.py # Tests des calculs de KPI
│ ├── test_ranking.py # Tests de classement
│ └── test_export.py # Tests du format Parquet
│
├── notebooks/
│ ├── pipeline_exploration.ipynb # Exploration initiale
│ └── debug_visuals.ipynb # Debug + visualisation
│
├── logs/
│ └── pipeline.log # Logs détaillés d’exécution
│
├── requirements.txt # Dépendances (PySpark, pytest, matplotlib...)
├── README.md # Documentation du projet
└── .gitignore # Fichiers à ignorer (parquet, cache, logs)
| KPI | Description | Formule |
|---|---|---|
| WinPercentage | Pourcentage de victoires | Wins / (Wins + Losses + Ties) |
| GoalsPerGame | Moyenne de buts marqués par match | GoalsScored / GamesPlayed |
| GoalsAgainstPerGame | Moyenne de buts encaissés par match | GoalsAgainst / GamesPlayed |
| GoalDifferentials | Différence de buts | GoalsScored - GoalsAgainst |
| Catégorie | Outils |
|---|---|
| Langage principal | Python 3.10+ |
| Traitement distribué | Apache Spark / PySpark |
| Stockage optimisé | Parquet partitionné |
| Exploration / Visualisation | Pandas, Matplotlib, Power BI |
| Environnement d’exécution | Google Colab, Databricks Community Edition |
| Gestion de version | GitHub |
- PySpark DataFrame API : pour les transformations distribuées.
- GroupBy & Aggregations : statistiques par équipe et saison.
- Window Functions : classement par saison.
- Parquet partitionné : stockage optimisé pour la lecture sélective.
- Matplotlib / Power BI : visualisation de la performance.
!pip install pyspark
from pyspark.sql import SparkSession
spark = SparkSession.builder.appName("FootballAnalysis").getOrCreate()
df = spark.read.csv("/content/football_matches.csv", header=True, inferSchema=True)df_final.write.mode("overwrite").partitionBy("Season").parquet("/content/football_stats_partitioned")df = spark.read.parquet("/content/football_stats_partitioned")
df.printSchema()football_stats_partitioned: contient toutes les équipes, partitionné par saison.football_top_teams: contient uniquement les champions de chaque saison.
- Pourcentage de victoires des champions
- Nombre de buts marqués par saison
- GoalDifferentials (différence de buts) par saison
- Recréer le pipeline dans un notebook Databricks Community Edition (CE).
- Comparer les performances entre Google Colab et Databricks.
- Utiliser la commande :
display(df)
-
Importer les fichiers
.parquetgénérés depuis le dossier :/data -
Créer un tableau de bord interactif comprenant :
-
Pourcentage de victoires (%Win)
-
Nombre de buts marqués (Goals)
-
Différence de buts (GoalDiff)
-
Ajouter des filtres dynamiques :
-
Par saison
-
Par équipe
- Apache Spark — Documentation officielle
- Databricks Community Edition
- Power BI — Importer des fichiers Parquet
- Football Data Source — Kaggle
- Football Data Europe
Salim Majide
🎓 Ingénieur Big Data & Cloud Computing (ENSET Mohammedia)
💼 Projet Data Engineering - PySpark
📧 Contact : LinkedIn
- Notebook Google Colab ou Databricks commenté
- Datasets Parquet :
/data/football_stats_partitioned/data/football_top_teams - Graphiques : Win%, Goals, GoalDiff
- Lien GitHub : Notebook, Datasets Parquet, Visualisations, README
Ce projet illustre la mise en œuvre complète d’un pipeline de données PySpark, depuis la préparation jusqu’à la visualisation, en appliquant les bonnes pratiques d’ingénierie de données, ainsi que les principes d’optimisation des performances et de déploiement sur Databricks et Power BI.