σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyParcours
Ctrl K
AO
+1,2 k apprenants
ConnexionRejoindre ↗
Parcours
AO
+1,2 k apprenants
Connexion
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Parcours Python›Module 2 · NumPy et pandas pour les données de marché›Sujet 2.8·~40 minDébutant

groupby et agrégation

Position dans le parcoursModule 2 sur 11 · Sujet 8 sur 20
2.8 groupby et agrégation
—Score du lab— / 100XP total—Série—

Découper, appliquer, combiner

Bien des questions demandent un nombre par groupe : l'exposition de chaque secteur, le rendement moyen de chaque stratégie, le nombre de transactions par jour. Le schéma est toujours le même, découper-appliquer-combiner (split-apply-combine). df.groupby("sector") découpe les lignes en groupes selon les valeurs d'une colonne, une agrégation comme .sum() est appliquée à chaque groupe, et pandas combine les résultats en un seul tableau indexé par les clés de groupe. Sans cela, on écrirait une boucle avec un dictionnaire de totaux ; avec cela, toute la question tient en une ligne : df.groupby("sector")["value"].sum().

import pandas as pd

df = pd.DataFrame({
    "symbol": ["AAPL", "MSFT", "GOOG", "TSLA", "F"],
    "sector": ["tech", "tech", "tech", "auto", "auto"],
    "value":  [36850.0, 20510.0, 51300.0, 30120.0, 9000.0],
    "ret":    [0.012, -0.004, 0.021, 0.03, -0.01],
})

print(df.groupby("sector")["value"].sum())
# sector
# auto      39120.0
# tech     108660.0
# Name: value, dtype: float64

print(df.groupby("sector").size().to_dict())             # {'auto': 2, 'tech': 3}  rows per group
print(df.groupby("sector")["ret"].mean().round(4).to_dict())   # {'auto': 0.01, 'tech': 0.0097}

Plusieurs résumés à la fois avec agg

.agg() calcule plusieurs résumés en une passe et permet de nommer les colonnes du résultat : df.groupby("sector").agg(count=("value", "size"), mean_return=("ret", "mean"), max_value=("value", "max")). Chaque mot-clé est le nom de la nouvelle colonne, et le tuple dit quelle colonne lire et quelle fonction appliquer ("sum", "mean", "min", "max", "std", "size", "first"...). On peut aussi grouper par plusieurs colonnes à la fois, groupby(["sector", "day"]), ce qui donne un résultat à index à deux niveaux. Les clés de groupe sont triées par défaut, et les lignes dont la clé est manquante (NaN) sont écartées.

import pandas as pd

df = pd.DataFrame({
    "symbol": ["AAPL", "MSFT", "GOOG", "TSLA", "F"],
    "sector": ["tech", "tech", "tech", "auto", "auto"],
    "value":  [36850.0, 20510.0, 51300.0, 30120.0, 9000.0],
    "ret":    [0.012, -0.004, 0.021, 0.03, -0.01],
})

summary = df.groupby("sector").agg(
    count=("value", "size"),
    mean_return=("ret", "mean"),
    max_value=("value", "max"),
)
print(summary)
#         count  mean_return  max_value
# sector
# auto        2     0.010000    30120.0
# tech        3     0.009667    51300.0

print(df.groupby("sector")["ret"].agg(["min", "max"]))   # a list of function names
#           min    max
# sector
# auto   -0.010  0.030
# tech   -0.004  0.021

transform : une statistique de groupe sur chaque ligne

Une agrégation réduit chaque groupe à une ligne. transform conserve la forme d'origine : il calcule la statistique du groupe et la répète sur chaque ligne du groupe, alignée sur l'index d'origine. C'est l'outil pour « la valeur d'une ligne comparée à son groupe » : la part d'une position dans son secteur est df["value"] / df.groupby("sector")["value"].transform("sum"), et centrer au sein d'un groupe s'écrit x - x.groupby(g).transform("mean"). Pour prendre des lignes entières par groupe, comme le meilleur élément de chaque secteur, utilisez idxmax() pour obtenir l'étiquette d'index du maximum de chaque groupe, puis sélectionnez ces lignes avec .loc.

import pandas as pd

df = pd.DataFrame({
    "symbol": ["AAPL", "MSFT", "GOOG", "TSLA", "F"],
    "sector": ["tech", "tech", "tech", "auto", "auto"],
    "value":  [36850.0, 20510.0, 51300.0, 30120.0, 9000.0],
    "ret":    [0.012, -0.004, 0.021, 0.03, -0.01],
})

totals = df.groupby("sector")["value"].transform("sum")      # one value per original row
print(totals.tolist())                       # [108660.0, 108660.0, 108660.0, 39120.0, 39120.0]
print((df["value"] / totals).round(3).tolist())   # [0.339, 0.189, 0.472, 0.77, 0.23]

best = df.loc[df.groupby("sector")["ret"].idxmax()].set_index("sector")[["symbol", "ret"]]
print(best)
#        symbol    ret
# sector
# auto     TSLA  0.030
# tech     GOOG  0.021
import pandas as pd

t = pd.DataFrame({
    "day":    ["mon", "mon", "tue", "tue"],
    "sector": ["tech", "auto", "tech", "tech"],
    "value":  [1.0, 2.0, 3.0, 4.0],
})

# Two keys give a two-level index
print(t.groupby(["day", "sector"])["value"].sum())
# day  sector
# mon  auto      2.0
#      tech      1.0
# tue  tech      7.0
# Name: value, dtype: float64

# reset_index() turns the keys back into ordinary columns
print(t.groupby(["day", "sector"])["value"].sum().reset_index())
#    day sector  value
# 0  mon   auto    2.0
# 1  mon   tech    1.0
# 2  tue   tech    7.0
Ne bouclez pas sur les groupes quand une méthode existeOn peut boucler avec for name, group in df.groupby("sector"):, ce qui convient pour afficher ou tracer quelques groupes, mais pour des nombres, les agrégations intégrées et transform sont plus courtes et bien plus rapides qu'une boucle Python ou qu'un apply avec une fonction. Vérifiez l'index du résultat (clés de groupe, en général triées) et ses dtypes, et rappelez-vous que size compte les lignes tandis que count compte les valeurs non manquantes.
  • df.groupby(clé)[col].sum() (ou mean, max, size...) : une valeur par groupe, indexée par les clés.
  • .agg(nom=(colonne, fonction), ...) produit plusieurs résumés nommés d'un coup.
  • transform garde le nombre de lignes (parts, centrage) ; idxmax + .loc prend des lignes entières par groupe.

À suivre : fusion et jointure de tableaux, pour combiner des tableaux qui partagent une clé, comme des prix et des données de référence.

Lab : ce qui est noté

  • Totaliser l'exposition de chaque secteur avec total_by_sector25 pts
  • Résumer chaque secteur en un seul tableau avec summary_by_sector25 pts
  • Mesurer chaque position par rapport à son secteur avec share_of_sector25 pts
  • Choisir le meilleur élément de chaque secteur avec best_per_sector25 pts
Explorateur · lab-41-1
▾ lab-41-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-41-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

Tout le contenu de lab-41-1 revient aux fichiers de départ et le terminal est vidé. Votre solution actuelle sera perdue : cette action est irréversible.

Sera réinitialisé
  • main.py → code de départ
  • Historique du terminal et sortie des tests
  • Modifications non soumises
Sera conservé
  • Meilleur score du lab
  • Votre XP et votre série
  • Progression du cours et notes

Connectez-vous pour exécuter votre code.

Tous les cours sont gratuits à lire. Créez un compte ou connectez-vous pour exécuter du code, lancer les tests et soumettre ce lab.

  • IDE dans le navigateur avec terminal bash — rien à installer
  • Correction instantanée, XP et votre place dans le parcours
Créer un compteSe connecter
OU
Continuer avec GitHub