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

Series pandas

Position dans le parcoursModule 2 sur 11 · Sujet 5 sur 20
2.5 Series pandas
—Score du lab— / 100XP total—Série—

Un tableau avec des étiquettes

Une Series pandas est un tableau à une dimension dans lequel chaque valeur porte une étiquette, conservée dans l'index de la Series. Au lieu de retenir que la position 1 est Microsoft, on demande prices["MSFT"]. Une Series a un name, un dtype comme un tableau NumPy, et elle accepte la même arithmétique sur tableaux entiers : prices * 2, prices.mean() et prices > 180 fonctionnent tous. On importe pandas par convention avec import pandas as pd ; il repose sur NumPy, vu dans les sujets précédents.

import pandas as pd

prices = pd.Series([184.25, 410.2, 171.0], index=["AAPL", "MSFT", "GOOG"], name="price")
print(prices)
# AAPL    184.25
# MSFT    410.20
# GOOG    171.00
# Name: price, dtype: float64

print(prices["AAPL"], prices.iloc[1])    # 184.25 410.2   by label, by position
print(prices.index.tolist())             # ['AAPL', 'MSFT', 'GOOG']
print(prices[prices > 180])              # keeps AAPL and MSFT, labels intact
print(prices.mean(), prices.idxmax())    # 255.15 MSFT

# A dict also builds a Series: keys become the index
print(pd.Series({"AAPL": 1, "MSFT": 2}))

L'alignement : les opérations associent les étiquettes, pas les positions

Quand on combine deux Series, pandas les aligne d'abord par étiquette. Les étiquettes présentes dans une seule donnent NaN (not a number, le marqueur de valeur manquante) dans le résultat, dont l'index est l'union des deux index. C'est exactement ce qu'il faut pour des positions détenues dans des comptes différents. Utilisez a.add(b, fill_value=0) pour traiter une étiquette absente comme zéro au lieu de produire NaN. La lecture par étiquette diffère aussi de NumPy : s["MSFT"] est par étiquette, tandis que s.iloc[1] est par position, et une étiquette inexistante lève KeyError.

import pandas as pd

a = pd.Series([100, 200], index=["AAPL", "MSFT"])
b = pd.Series([50, 10], index=["MSFT", "GOOG"])

print(a + b)
# AAPL      NaN
# GOOG      NaN
# MSFT    250.0

print(a.add(b, fill_value=0))
# AAPL    100.0
# GOOG     10.0
# MSFT    250.0

# Selecting by a list of labels, and asking for one that is missing
prices = pd.Series([184.25, 410.2], index=["AAPL", "MSFT"])
print(prices.reindex(["MSFT", "TSLA"]).tolist())   # [410.2, nan]

Tri, classement et mise en base

s.sort_values(ascending=False) ordonne par valeur en emportant les étiquettes, s.sort_index() ordonne par étiquette et s.abs() prend les valeurs absolues. Tri plus découpage donnent les plus gros mouvements : r.abs().sort_values(ascending=False).index[:3] renvoie les trois étiquettes au plus grand rendement absolu. Pour comparer des actifs cotant à des niveaux de prix différents, mettez chacun en base 100 au départ : s / s.iloc[0] * 100, qui conserve l'index et le nom. Les valeurs manquantes (NaN) sont ignorées par sum, mean et consorts ; s.isna() les repère.

import pandas as pd

r = pd.Series([0.01, -0.03, 0.02], index=["x", "y", "z"])
print(r.abs().sort_values(ascending=False))
# y    0.03
# z    0.02
# x    0.01
# dtype: float64

prices = pd.Series([184.25, 410.2, 171.0], index=["AAPL", "MSFT", "GOOG"], name="price")
print(prices / prices.iloc[0] * 100)           # rebased to 100 at the first value
# AAPL    100.000000
# MSFT    222.632293
# GOOG     92.808684
# Name: price, dtype: float64

gappy = pd.Series([1.0, None, 3.0])
print(gappy.sum(), gappy.mean(), gappy.isna().tolist())   # 4.0 2.0 [False, True, False]
import pandas as pd

# A stray space and a lower-case letter make "the same" symbol two labels
raw = pd.Series([1, 2], index=["AAPL", "aapl "])
print(raw.index.is_unique)                     # True: they look different

raw.index = raw.index.str.strip().str.upper()  # clean the labels
print(raw.index.is_unique)                     # False: now both are "AAPL"
print(raw["AAPL"].tolist())                    # [1, 2]   a duplicate label returns a Series

merged = raw.groupby(level=0).sum()            # combine duplicates (groupby comes soon)
print(merged.to_dict())                        # {'AAPL': 3}
Les étiquettes sont aussi des données : doublons et fautes de frappeL'alignement vaut ce que valent les étiquettes. "AAPL" et "aapl " sont des étiquettes différentes : une faute de frappe produit silencieusement des lignes NaN ; nettoyez les étiquettes (strip, upper) avant de combiner. Un index peut contenir des doublons, et alors s["AAPL"] renvoie une Series au lieu d'une valeur : vérifiez s.index.is_unique pour des données censées avoir une valeur par étiquette. Les opérations renvoient de nouvelles Series, l'original reste intact, comportement que vérifient les tests du lab.
  • pd.Series(values, index=labels, name=...) ; lire par étiquette s["A"] ou par position s.iloc[0].
  • Les opérations s'alignent sur les étiquettes (index union, NaN si absent) ; a.add(b, fill_value=0) traite un trou comme 0.
  • sort_values, abs, idxmax, s / s.iloc[0] * 100 ; les résultats sont de nouvelles Series, l'original reste inchangé.

À suivre : les DataFrames pandas, des tableaux faits de Series qui partagent un même index.

Lab : ce qui est noté

  • Étiqueter des prix par symbole avec price_series25 pts
  • Additionner deux comptes par étiquette avec total_exposure25 pts
  • Trouver les plus gros mouvements avec top_movers25 pts
  • Mettre chaque prix en base 100 avec rebase_to_10025 pts
Explorateur · lab-38-1
▾ lab-38-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-38-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

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