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

Fusionner et joindre des tables

Position dans le parcoursModule 2 sur 11 · Sujet 9 sur 20
2.9 Fusionner et joindre des tables
—Score du lab— / 100XP total—Série—

Des tableaux qui partagent une clé

Les données réelles arrivent rarement dans un seul tableau. Vos positions sont dans l'un, le secteur de chaque symbole dans un autre, les prix dans un troisième. Ce qui les relie est une clé, ici le symbole. left.merge(right, on="clé") trouve, pour chaque ligne de left, les lignes de right ayant la même clé et les met côte à côte. C'est la même idée qu'une jointure en SQL.

import pandas as pd

positions = pd.DataFrame({"symbol": ["AAPL", "MSFT", "TSLA", "GOOG"], "qty": [100, 50, 20, 10]})
reference = pd.DataFrame({"symbol": ["AAPL", "MSFT", "GOOG", "F"], "sector": ["tech", "tech", "tech", "auto"]})

merged = positions.merge(reference, on="symbol")
print(merged)
#   symbol  qty sector
# 0   AAPL  100   tech
# 1   MSFT   50   tech
# 2   GOOG   10   tech

inner, left, right et outer

TSLA a disparu du résultat ci-dessus, et F aussi. Le choix par défaut, how="inner", ne garde que les clés présentes dans les deux tableaux. Dites ce que vous voulez : how="left" garde toutes les lignes du tableau de gauche et complète les valeurs manquantes de droite par NaN, how="right" fait l'inverse, et how="outer" garde les clés des deux. Pour enrichir un tableau, on veut presque toujours left, car il ne perd jamais une ligne en silence.

# how="left" keeps every position; TSLA has no sector, so it gets NaN
left = positions.merge(reference, on="symbol", how="left")
print(left)
#   symbol  qty sector
# 0   AAPL  100   tech
# 1   MSFT   50   tech
# 2   TSLA   20    NaN
# 3   GOOG   10   tech

# how="outer" keeps the keys of both tables (sorted); quantities become floats because of the NaN
print(positions.merge(reference, on="symbol", how="outer"))
#   symbol    qty sector
# 0   AAPL  100.0   tech
# 1      F    NaN   auto
# 2   GOOG   10.0   tech
# 3   MSFT   50.0   tech
# 4   TSLA   20.0    NaN

Trouver ce qui ne correspond pas

Un NaN silencieux peut cacher un problème de données, alors vérifiez-le. indicator=True ajoute une colonne _merge qui indique, pour chaque ligne, si la clé a été trouvée dans left_only, right_only ou both. La filtrer répond à des questions comme « quelles positions n'ont pas de prix ? ». Les clés en double sont l'autre piège : si une clé apparaît deux fois à droite, chaque ligne correspondante de gauche est répétée. Passez validate="many_to_one" (ou "one_to_one") et pandas lève une erreur au lieu de changer discrètement le nombre de lignes.

# Which positions have no sector?
check = positions.merge(reference, on="symbol", how="left", indicator=True)
print(check)
#   symbol  qty sector     _merge
# 0   AAPL  100   tech       both
# 1   MSFT   50   tech       both
# 2   TSLA   20    NaN  left_only
# 3   GOOG   10   tech       both

print(check.loc[check["_merge"] == "left_only", "symbol"].tolist())   # ['TSLA']
# Duplicate keys repeat rows: AAPL has two quotes, so the AAPL position appears twice
quotes = pd.DataFrame({"symbol": ["AAPL", "AAPL", "MSFT"], "price": [184.25, 184.5, 410.1]})
print(len(positions.merge(quotes, on="symbol")))   # 3

# validate turns the surprise into an error
try:
    positions.merge(quotes, on="symbol", validate="one_to_one")
except Exception as error:
    print(type(error).__name__)   # MergeError

Clés de noms différents et colonnes en conflit

Quand la clé porte des noms différents dans les deux tableaux, utilisez left_on="symbol", right_on="ticker" ; les deux colonnes sont conservées. Quand les deux tableaux ont une colonne de même nom qui n'est pas la clé (ici qty), pandas garde les deux et ajoute les suffixes _x et _y. Choisissez-en de plus clairs avec suffixes=("_a", "_b"). Après une jointure externe, les quantités manquantes sont NaN et la colonne est de type flottant : utilisez fillna(0) puis astype("int64") pour retrouver des entiers.

# Different key names: both columns are kept
book_a = pd.DataFrame({"symbol": ["AAPL", "MSFT"], "qty": [100, 50]})
book_b = pd.DataFrame({"ticker": ["MSFT", "TSLA"], "qty": [-20, 30]})
print(book_a.merge(book_b, left_on="symbol", right_on="ticker", how="outer", suffixes=("_a", "_b")))
#   symbol  qty_a ticker  qty_b
# 0   AAPL  100.0    NaN    NaN
# 1   MSFT   50.0   MSFT  -20.0
# 2    NaN    NaN   TSLA   30.0

# Same key name, outer join, suffixes, then back to whole numbers
both = book_a.merge(book_b.rename(columns={"ticker": "symbol"}), on="symbol", how="outer", suffixes=("_a", "_b"))
both[["qty_a", "qty_b"]] = both[["qty_a", "qty_b"]].fillna(0).astype("int64")
print(both)
#   symbol  qty_a  qty_b
# 0   AAPL    100      0
# 1   MSFT     50    -20
# 2   TSLA      0     30
Comptez les lignes après chaque fusionUne fusion qui perd ou répète des lignes en silence fausse tout ce qui suit, sans qu'aucune erreur ne vous prévienne. Comparez len() avant et après, utilisez how="left" pour garder toutes les lignes, et ajoutez validate= quand vous croyez les clés uniques.
  • left.merge(right, on="clé") fait correspondre les lignes de deux tableaux qui partagent une clé ; left_on / right_on gèrent des noms différents.
  • how="inner" (défaut) garde les clés des deux, "left" garde toutes les lignes de gauche, "outer" garde toutes les clés.
  • indicator=True montre ce qui ne correspond pas ; validate= et suffixes= protègent des clés en double et des noms en conflit.

À suivre : les rendements simples, qui transforment une série de prix en variation en pourcentage d'une période à l'autre.

Lab : ce qui est noté

  • Ajouter le secteur de chaque transaction avec attach_sector25 pts
  • Valoriser les positions qui ont un prix avec value_positions25 pts
  • Trouver les positions sans prix avec unpriced_symbols25 pts
  • Réunir deux livres en un seul tableau avec combine_books25 pts
Explorateur · lab-42-1
▾ lab-42-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-42-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

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