GaiaEx AcademyGaiaEx Academy
Analyse de données avec Pandas, NumPy et Matplotlib
DéveloppeurProgrammation12 min read

Analyse de données avec Pandas, NumPy et Matplotlib

Nettoyer, transformer et visualiser des données financières comme un quant

Partager les articles

NumPy : le moteur sous le capot

Tout calcul financier sérieux en Python passe finalement par NumPy. Si les listes Python sont flexibles, elles sont lentes — chaque élément est un objet Python complet avec la surcharge de vérification de type. Les tableaux NumPy stockent des nombres bruts dans des blocs de mémoire contigus, permettant des opérations 100 fois plus rapides que des boucles Python pures.

Voici la différence en pratique :

import numpy as np

# Créer un tableau de 1 million de rendements journaliers aléatoires
returns = np.random.normal(0.0005, 0.02, 1_000_000)

# Opérations vectorisées — pas de boucles nécessaires
cumulative = np.cumprod(1 + returns)  # Croissance de $1
sharpe = returns.mean() / returns.std() * np.sqrt(252)
max_drawdown = np.min(cumulative / np.maximum.accumulate(cumulative) - 1)

print(f"Sharpe Ratio: {sharpe:.3f}")
print(f"Max Drawdown: {max_drawdown:.2%}")

Concepts NumPy clés pour la finance :

  • Opérations vectorisées — Appliquez des calculs à des tableaux entiers d'un coup au lieu de boucler élément par élément.
  • Broadcasting — Aligne automatiquement des tableaux de formes différentes pour l'arithmétique (par exemple, soustraire une moyenne scalaire de chaque élément).
  • Algèbre linéairenp.linalg fournit la multiplication matricielle, la décomposition en valeurs propres, et les solveurs utilisés dans l'optimisation de portefeuille.
  • Échantillonnage aléatoire — Les simulations Monte Carlo, l'échantillonnage bootstrap et la modélisation stochastique reposent tous sur np.random.

Astuce de performance : préférez toujours les opérations NumPy vectorisées aux boucles for Python. Une optimisation de portefeuille sur 500 actifs qui prend 30 secondes avec des boucles peut se terminer en moins de 50 millisecondes avec du NumPy vectorisé — une accélération de 600 fois.

NumPy : mémoire contiguë + opérations vectorisées ndarray — dtype, shape, strides (C-contigu) une boucle en C/Fortran, pas un million d'étapes de bytecode Python broadcasting : aligner les formes pour les calculs élément par élément ex. vecteur des rendements − moyenne scalaire, ou (n,) avec les lignes d'une matrice (n, m) linalg : cov, eig, solve — les calculs de portefeuille vivent ici
Les tableaux sont la voie rapide ; le broadcasting permet de garder le code lisible sans boucles.

Pandas : des DataFrames pour les données financières

Si NumPy est le moteur, pandas est le tableau de bord. Il enveloppe les tableaux NumPy dans des structures étiquetées et indexées qui rendent la manipulation des données financières intuitive et expressive.

Les deux structures principales sont :

  • Series — Une seule colonne de données avec un index (pensez : une série chronologique de prix de clôture).
  • DataFrame — Un tableau de colonnes, chacune étant une Series, partageant un index commun (pensez : des données de bougies OHLCV).

Charger et inspecter des données est simple :

import pandas as pd

# Lire depuis un CSV
df = pd.read_csv("btc_daily.csv", parse_dates=["date"], index_col="date")

# Ou depuis du JSON (courant dans les réponses d'API)
df = pd.read_json("https://api.example.com/candles?symbol=ETH")

# Inspection rapide
print(df.shape)          # (365, 5)
print(df.dtypes)         # Types des colonnes
print(df.describe())     # Résumé statistique
print(df.tail())         # 5 dernières lignes

Ce qui rend pandas indispensable pour la finance, c'est son DatetimeIndex. Une fois que votre index est de type datetime, vous débloquez des opérations puissantes sur les séries temporelles :

# Découper par plage de dates
q1_data = df["2025-01":"2025-03"]

# Rééchantillonner des données journalières en OHLC hebdomadaire
weekly = df["close"].resample("W").ohlc()

# Remplissage avant (forward-fill) des données manquantes (week-ends, jours fériés)
df = df.asfreq("D").ffill()

Ces opérations gèrent les réalités désordonnées des données financières — trous, différences de fuseaux horaires, horodatages irréguliers — pour que vous puissiez vous concentrer sur l'analyse plutôt que sur la plomberie des données.

Calculs glissants : moyennes mobiles et volatilité

L'analyse financière est intrinsèquement fenêtrée. Vous vous souciez rarement d'un seul point de donnée isolé — le contexte vient de sa relation à l'historique récent. La méthode .rolling() de pandas est votre outil principal ici.

import pandas as pd
import numpy as np

# Supposons que df a une colonne "close" avec un DatetimeIndex
df["sma_20"] = df["close"].rolling(20).mean()
df["sma_50"] = df["close"].rolling(50).mean()
df["ema_12"] = df["close"].ewm(span=12).mean()

# Rendements journaliers et volatilité glissante
df["returns"] = df["close"].pct_change()
df["vol_30d"] = df["returns"].rolling(30).std() * np.sqrt(365)

# Bandes de Bollinger
df["bb_upper"] = df["sma_20"] + 2 * df["close"].rolling(20).std()
df["bb_lower"] = df["sma_20"] - 2 * df["close"].rolling(20).std()

# Corrélation glissante entre deux actifs
df["corr_btc_eth"] = df["btc_returns"].rolling(60).corr(df["eth_returns"])

Calculs glissants clés que chaque trader devrait connaître :

  • Moyenne mobile simple (SMA) — Moyenne à pondération égale sur N périodes. Retardée mais stable.
  • Moyenne mobile exponentielle (EMA) — Pondère plus fortement les données récentes via .ewm(). Plus réactive aux changements de prix.
  • Volatilité glissante — Écart-type des rendements sur une fenêtre, annualisé. Essentielle pour le sizing de position et les budgets de risque.
  • Corrélation glissante — Mesure comment deux actifs évoluent ensemble dans le temps. Critique pour la diversification de portefeuille.

Sur des plateformes comme GaiaEx, vous pouvez récupérer des données de bougies historiques via l'API de trading, les charger dans un DataFrame pandas, et calculer ces indicateurs en quelques secondes — tout en gardant vos actifs en sécurité dans votre portefeuille MPC.

GroupBy et agrégation pour l'analyse de portefeuille

Quand vous gérez plusieurs actifs, .groupby() devient essentiel. Il vous permet de diviser les données par catégorie, appliquer des calculs, et combiner les résultats — le modèle split-apply-combine.

# DataFrame avec plusieurs actifs
trades = pd.DataFrame({
    "symbol": ["BTC", "ETH", "BTC", "SOL", "ETH", "BTC"],
    "side": ["buy", "buy", "sell", "buy", "sell", "buy"],
    "pnl": [120.5, -45.2, 89.0, 210.3, 55.8, -30.1],
    "volume": [5000, 3200, 4800, 1500, 2900, 5100],
})

# Performance par actif
summary = trades.groupby("symbol").agg(
    total_pnl=("pnl", "sum"),
    avg_pnl=("pnl", "mean"),
    trade_count=("pnl", "count"),
    total_volume=("volume", "sum"),
    win_rate=("pnl", lambda x: (x > 0).mean()),
)

print(summary.sort_values("total_pnl", ascending=False))

Modèles d'agrégation avancés pour le travail de portefeuille :

  • GroupBy multi-niveaux — Grouper par symbole et côté pour voir la performance long contre short par actif.
  • Fonctions d'agrégation personnalisées — Calculer les ratios de Sharpe, les ratios de Sortino, ou le drawdown maximal par groupe d'actifs.
  • Tableaux croisés dynamiques — Remodeler les données pour voir les rendements mensuels par actif dans un format adapté à une heatmap avec pd.pivot_table().
  • Rééchantillonnage avec groupby — Combiner le rééchantillonnage temporel avec le groupement catégoriel pour une analyse multi-actifs de séries temporelles.

Matplotlib : représenter l'action des prix et les signaux

Des données sans visualisation ne sont que des chiffres. Matplotlib transforme votre analyse en graphiques qui révèlent des motifs invisibles dans les données brutes.

import matplotlib.pyplot as plt
import matplotlib.dates as mdates

fig, axes = plt.subplots(3, 1, figsize=(14, 10),
                         sharex=True, gridspec_kw={"height_ratios": [3, 1, 1]})

# Prix + Moyennes mobiles
axes[0].plot(df.index, df["close"], label="Close", linewidth=1.2)
axes[0].plot(df.index, df["sma_20"], label="SMA 20", linestyle="--")
axes[0].fill_between(df.index, df["bb_upper"], df["bb_lower"],
                     alpha=0.1, color="blue", label="Bollinger Bands")
axes[0].set_ylabel("Price (USD)")
axes[0].legend(loc="upper left")

# Barres de volume
colors = ["green" if c > o else "red"
          for c, o in zip(df["close"], df["open"])]
axes[1].bar(df.index, df["volume"], color=colors, alpha=0.7)
axes[1].set_ylabel("Volume")

# Volatilité glissante
axes[2].plot(df.index, df["vol_30d"], color="purple")
axes[2].set_ylabel("30d Volatility")
axes[2].axhline(y=0.8, color="red", linestyle=":", alpha=0.5)

axes[2].xaxis.set_major_formatter(mdates.DateFormatter("%b %Y"))
plt.tight_layout()
plt.savefig("analysis_dashboard.png", dpi=150)
plt.show()

Cela produit un tableau de bord professionnel à trois panneaux : l'action des prix avec les bandes de Bollinger en haut, le volume au milieu, et la volatilité en bas. Cette disposition reflète ce que vous verriez sur des terminaux de trading professionnels.

Pour la visualisation statistique, seaborn s'appuie sur Matplotlib avec des fonctions de plus haut niveau :

import seaborn as sns

# Distribution des rendements
sns.histplot(df["returns"].dropna(), bins=100, kde=True)

# Heatmap de corrélation entre actifs
corr_matrix = portfolio_returns.corr()
sns.heatmap(corr_matrix, annot=True, cmap="RdYlGn", center=0)
Pandas → analyse ; Matplotlib → compréhension DataFrame index + colonnes rolling resample groupby Métriques Series rendements, vol, Sharpe matplotlib.pyplot — figure, axes, artists prix volume indicateurs seaborn optionnel — même couche Artist, valeurs par défaut plus soignées
Pandas prépare des tableaux ordonnés ; Matplotlib les mappe vers des axes que vous pouvez annoter et partager.

Tout assembler : un pipeline d'analyse complet

La véritable puissance émerge quand vous enchaînez ces outils en un pipeline reproductible. Voici un flux de travail que les quants professionnels utilisent quotidiennement :

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

def analyze_asset(symbol: str, df: pd.DataFrame) -> dict:
    """Pipeline d'analyse complet pour un seul actif."""
    df["returns"] = df["close"].pct_change()
    df["log_returns"] = np.log(df["close"] / df["close"].shift(1))

    return {
        "symbol": symbol,
        "total_return": (df["close"].iloc[-1] / df["close"].iloc[0]) - 1,
        "annual_vol": df["returns"].std() * np.sqrt(365),
        "sharpe": df["returns"].mean() / df["returns"].std() * np.sqrt(365),
        "max_drawdown": (df["close"] / df["close"].cummax() - 1).min(),
        "skewness": df["returns"].skew(),
        "kurtosis": df["returns"].kurtosis(),
    }

# Analyser plusieurs actifs
results = [analyze_asset(sym, data) for sym, data in assets.items()]
summary = pd.DataFrame(results).set_index("symbol")
print(summary.round(4))

Ce pipeline prend des données de prix brutes et produit un profil complet de risque-rendement pour chaque actif. À partir de là, vous pouvez injecter ces métriques dans un optimiseur de portefeuille, générer des recommandations d'allocation, ou déclencher des signaux de rééquilibrage.

La pile pandas-NumPy-Matplotlib est le socle sur lequel repose tout le reste de la finance en Python. Maîtrisez ces trois bibliothèques et vous aurez les compétences pour analyser n'importe quel marché, construire n'importe quel indicateur, et visualiser n'importe quelle stratégie — que vous échangiez des actions sur NYSE, de la crypto sur GaiaEx, ou des produits dérivés sur CME.