σμ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.6·~45 minDébutant

DataFrames pandas

Position dans le parcoursModule 2 sur 11 · Sujet 6 sur 20
2.6 DataFrames pandas
—Score du lab— / 100XP total—Série—

Un tableau de colonnes étiquetées

Un DataFrame est un tableau à deux dimensions : un ensemble de colonnes, chacune une Series, qui partagent un même index d'étiquettes de lignes. C'est le cheval de trait de l'analyse de données de marché : une ligne par symbole ou par jour, une colonne par champ (prix, volume, rendement). On en construit un à partir d'un dictionnaire de colonnes, pd.DataFrame({"price": [...], "volume": [...]}, index=symbols), ou d'une liste de dictionnaires de lignes. Chaque colonne a son propre dtype (les prix sont float64, les volumes int64), contrairement à un tableau NumPy qui a un seul dtype pour tout.

import pandas as pd

df = pd.DataFrame(
    {"price": [184.25, 410.2, 171.0], "volume": [200, 50, 300]},
    index=["AAPL", "MSFT", "GOOG"],
)
print(df)
#        price  volume
# AAPL  184.25     200
# MSFT  410.20      50
# GOOG  171.00     300

print(df.shape, df.columns.tolist())              # (3, 2) ['price', 'volume']
print(df.dtypes.astype(str).to_dict())            # {'price': 'float64', 'volume': 'int64'}

rows = [{"symbol": "AAPL", "price": 184.25}, {"symbol": "MSFT", "price": 410.2}]
print(pd.DataFrame(rows))                         # from a list of row dictionaries
#   symbol   price
# 0   AAPL  184.25
# 1   MSFT  410.20

Colonnes, nouvelles colonnes et lignes filtrées

df["price"] est une colonne, une Series ; df[["price"]] avec une liste est un DataFrame d'une colonne. Une nouvelle colonne vient d'une arithmétique sur les colonnes : df.assign(notional=df["price"] * df["volume"]) renvoie un nouveau tableau avec la colonne en plus et laisse df intact (écrire df["notional"] = ... modifie df lui-même). Une condition booléenne sur une colonne filtre les lignes, df[df["volume"] >= 100], et df.sort_values("volume", ascending=False) les ordonne, .head(n) gardant les n premières. Tout cela opère sur des colonnes entières d'un coup : ne bouclez jamais sur les lignes avec iterrows() quand une opération de colonne existe.

import pandas as pd

df = pd.DataFrame(
    {"price": [184.25, 410.2, 171.0], "volume": [200, 50, 300]},
    index=["AAPL", "MSFT", "GOOG"],
)

bigger = df.assign(notional=df["price"] * df["volume"])   # a new frame
print(bigger)
#        price  volume  notional
# AAPL  184.25     200   36850.0
# MSFT  410.20      50   20510.0
# GOOG  171.00     300   51300.0
print(df.columns.tolist())                                # ['price', 'volume']  df is unchanged

print(df[df["volume"] >= 100])                            # rows that pass the test
#        price  volume
# AAPL  184.25     200
# GOOG  171.00     300

print(df.sort_values("volume", ascending=False).head(2))  # the two biggest volumes
#        price  volume
# GOOG  171.00     300
# AAPL  184.25     200

Résumés et coup d'œil sur les données

Regardez toujours un tableau avant de lui faire confiance. df.head() montre les premières lignes, df.shape donne (lignes, colonnes), df.dtypes liste le type de chaque colonne, df.isna().sum() compte les valeurs manquantes par colonne et df.describe() résume les colonnes numériques (effectif, moyenne, écart type, minimum, quartiles, maximum). Les méthodes de colonne comme df.mean() donnent une valeur par colonne ; df.sum(axis=1) en donne une par ligne. Un dtype object ou str là où l'on attendait des nombres signifie en général que du texte s'est glissé dans la colonne.

import pandas as pd

df = pd.DataFrame(
    {"price": [184.25, 410.2, 171.0], "volume": [200, 50, 300]},
    index=["AAPL", "MSFT", "GOOG"],
)

print(df.describe().loc[["count", "mean", "max"]])
#         price      volume
# count    3.00    3.000000
# mean   255.15  183.333333
# max    410.20  300.000000

print(df.mean().to_dict())                 # {'price': 255.15, 'volume': 183.33333333333334}
print(df.sum(axis=1).tolist())             # [384.25, 460.2, 471.0]   one value per row
print(df.isna().sum().to_dict())           # {'price': 0, 'volume': 0}

# Changing a copy never changes the original (pandas 3 copies on write)
cheap = df[df["price"] < 200].copy()
cheap.loc["AAPL", "price"] = 0.0
print(df.loc["AAPL", "price"])             # 184.25
import pandas as pd

rows = [
    {"symbol": "AAPL", "price": 184.25, "volume": 200},
    {"symbol": "MSFT", "price": 410.2, "volume": 50},
]
df = pd.DataFrame(rows).set_index("symbol")      # make a column the row labels
print(df)
#          price  volume
# symbol
# AAPL    184.25     200
# MSFT    410.20      50

print(df.rename(columns={"price": "px"}).columns.tolist())   # ['px', 'volume']
print(df.drop(columns="volume").columns.tolist())             # ['price']
print(df.reset_index().columns.tolist())                      # ['symbol', 'price', 'volume']
Renvoyez de nouveaux tableaux, ne modifiez pas celui de l'appelantUne fonction qui reçoit un DataFrame devrait le traiter en lecture seule et en renvoyer un nouveau : utilisez assign, le filtrage booléen et sort_values, qui renvoient tous de nouveaux tableaux. Le bogue classique consiste à écrire une nouvelle colonne dans l'argument, ce qui l'ajoute silencieusement au tableau de l'appelant. Les tests du lab comparent l'argument avant et après précisément pour cela.
  • pd.DataFrame({colonne: valeurs}, index=labels) ; df["c"] est une Series, df[["c"]] un DataFrame ; chaque colonne a son dtype.
  • assign ajoute une colonne à un nouveau tableau ; df[masque] filtre les lignes ; sort_values(...).head(n) prend les n premiers.
  • Regardez d'abord : shape, dtypes, head(), describe(), isna().sum() ; ne modifiez jamais le tableau de l'appelant.

À suivre : sélectionner des données avec loc et iloc, les deux façons précises de choisir lignes et colonnes par étiquette ou par position.

Lab : ce qui est noté

  • Construire un tableau de prix et de volumes avec make_frame25 pts
  • Ajouter une colonne de valeur échangée avec add_notional25 pts
  • Ne garder que les lignes liquides avec filter_liquid25 pts
  • Classer les lignes selon une colonne avec top_by25 pts
Explorateur · lab-39-1
▾ lab-39-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-39-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

Tout le contenu de lab-39-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