σμ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 AcademySkills
Ctrl K
AO
+1,2 Tsd. Lernende
AnmeldenBeitreten ↗
Skills
AO
+1,2 Tsd. Lernende
Anmelden
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python-Skill›Modul 2 · NumPy & pandas für Marktdaten›Thema 2.8·~40 Min.Einsteiger

groupby und Aggregation

Position in der SkillModul 2 von 11 · Thema 8 von 20
2.8 groupby und Aggregation
—Lab-Punkte— / 100XP gesamt—Serie—

Aufteilen, anwenden, zusammenführen

Viele Fragen verlangen eine Zahl pro Gruppe: das Exposure jedes Sektors, die Durchschnittsrendite jeder Strategie, die Zahl der Trades pro Tag. Das Muster ist immer dasselbe, Split-Apply-Combine. df.groupby("sector") teilt die Zeilen nach den Werten einer Spalte in Gruppen, eine Aggregation wie .sum() wird auf jede Gruppe angewandt, und pandas führt die Ergebnisse in einer Tabelle zusammen, die nach den Gruppenschlüsseln indiziert ist. Ohne das schriebe man eine Schleife mit einem Dictionary laufender Summen; damit passt die ganze Frage in eine Zeile: 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}

Mehrere Zusammenfassungen auf einmal mit agg

.agg() berechnet mehrere Zusammenfassungen in einem Durchgang und erlaubt es, die Ergebnisspalten zu benennen: df.groupby("sector").agg(count=("value", "size"), mean_return=("ret", "mean"), max_value=("value", "max")). Jedes Schlüsselwort ist der neue Spaltenname, und das Tupel sagt, welche Spalte gelesen und welche Funktion angewandt wird ("sum", "mean", "min", "max", "std", "size", "first"...). Man kann auch nach mehreren Spalten gruppieren, groupby(["sector", "day"]), was ein Ergebnis mit zweistufigem Index liefert. Die Gruppenschlüssel werden standardmäßig sortiert, und Zeilen mit fehlendem Schlüssel (NaN) entfallen.

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: eine Gruppenstatistik in jeder Zeile

Eine Aggregation schrumpft jede Gruppe auf eine Zeile. transform behält die ursprüngliche Form: Es berechnet die Gruppenstatistik und wiederholt sie in jeder Zeile der Gruppe, ausgerichtet am ursprünglichen Index. Damit eignet es sich für „der Wert einer Zeile im Vergleich zu ihrer Gruppe“: Der Anteil einer Position an ihrem Sektor ist df["value"] / df.groupby("sector")["value"].transform("sum"), und das Zentrieren innerhalb einer Gruppe ist x - x.groupby(g).transform("mean"). Um ganze Zeilen pro Gruppe zu wählen, etwa den besten Wert jedes Sektors, liefert idxmax() das Indexlabel des Maximums jeder Gruppe, die Sie dann mit .loc auswählen.

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
Laufen Sie nicht über Gruppen, wenn es eine Methode gibtMan kann mit for name, group in df.groupby("sector"): iterieren, was zum Ausgeben oder Zeichnen weniger Gruppen taugt, doch für Zahlen sind die eingebauten Aggregationen und transform kürzer und viel schneller als eine Python-Schleife oder apply mit einer Funktion. Prüfen Sie den Index des Ergebnisses (Gruppenschlüssel, meist sortiert) und die dtypes, und denken Sie daran, dass size Zeilen zählt, count dagegen nicht fehlende Werte.
  • df.groupby(schlüssel)[col].sum() (oder mean, max, size...): ein Wert pro Gruppe, nach den Schlüsseln indiziert.
  • .agg(name=(spalte, funktion), ...) erzeugt mehrere benannte Zusammenfassungen auf einmal.
  • transform behält die Zeilenzahl (Anteile, Zentrierung); idxmax + .loc wählt ganze Zeilen pro Gruppe.

Als Nächstes: Tabellen zusammenführen und verbinden, Tabellen mit gemeinsamem Schlüssel verknüpfen, etwa Preise und Stammdaten.

Lab: Was bewertet wird

  • Mit total_by_sector das Exposure jedes Sektors summieren25 Pkt.
  • Mit summary_by_sector jeden Sektor in einer Tabelle zusammenfassen25 Pkt.
  • Mit share_of_sector jede Position an ihrem Sektor messen25 Pkt.
  • Mit best_per_sector den besten Wert jedes Sektors auswählen25 Pkt.
Explorer · lab-41-1
▾ lab-41-1
…
bash · im Browser
learner@quantcraft:~/lab-41-1$
Python noch nicht geladenPythonLn 1, Col 1Spaces: 4UTF-8

Dieses Thema zurücksetzen?

Alles in lab-41-1 wird auf die Startdateien zurückgesetzt und das Terminal geleert. Ihre aktuelle Lösung geht verloren – das lässt sich nicht rückgängig machen.

Wird zurückgesetzt
  • main.py → Startcode
  • Terminal-Verlauf und Testausgabe
  • Nicht eingereichte Änderungen
Bleibt erhalten
  • Beste Lab-Punktzahl
  • Ihre XP und Ihre Serie
  • Vorlesungsfortschritt und Notizen

Melde dich an, um deinen Code auszuführen.

Alle Lektionen kannst du kostenlos lesen. Erstelle ein Konto oder melde dich an, um Code auszuführen, Tests zu starten und dieses Lab abzugeben.

  • IDE im Browser mit Bash-Terminal — nichts zu installieren
  • Sofortige Bewertung, XP und dein Platz auf der Skill
Konto erstellenAnmelden
ODER
Weiter mit GitHub