σμ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 Academyロードマップ
Ctrl K
AO
+1.2k 人の学習者
ログイン参加する ↗
ロードマップ
AO
+1.2k 人の学習者
ログイン
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python ロードマップ›モジュール 2 · 市場データのためのNumPyとpandas›トピック 2.5·~40 分初級

pandasのSeries

ロードマップ上の位置モジュール 2/11 · トピック 5/20
2.5 pandasのSeries
—ラボスコア— / 100合計XP—連続日数—

ラベル付きの配列

pandas の Series は、各値にラベルが付いた1次元の配列で、ラベルは Series のインデックスに保持されます。位置1がマイクロソフトだと覚える代わりに prices["MSFT"] と尋ねます。Series には name があり、NumPy 配列と同じように dtype を持ち、配列全体の演算も同様に使えるので、prices * 2、prices.mean()、prices > 180 はすべて動きます。pandas は慣習で import pandas as pd とインポートし、前のトピックで学んだ NumPy の上に作られています。

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}))

アライメント:演算は位置ではなくラベルで対応づけられる

2つの Series を組み合わせると、pandas はまずラベルで揃えます。片方にしかないラベルは結果で NaN(not a number、欠損値の印)になり、結果のインデックスは両方のインデックスの和集合です。異なる口座にあるポジションの合算にはまさに必要な動作です。a.add(b, fill_value=0) を使うと、欠けたラベルを NaN ではなく0として扱います。ラベルでの読み取りも NumPy とは異なります。s["MSFT"] はラベル、s.iloc[1] は位置で、存在しないラベルは 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]

並べ替え・順位付け・基準化

s.sort_values(ascending=False) は値で並べ替え、ラベルも一緒に動かします。s.sort_index() はラベル順、s.abs() は絶対値です。並べ替えとスライスで大きな動きが見つかります。r.abs().sort_values(ascending=False).index[:3] は絶対リターンが大きい3つのラベルを返します。価格水準の異なる資産を比べるには、開始時点を100に基準化します:s / s.iloc[0] * 100(インデックスと名前は保たれます)。欠損値(NaN)は sum や mean などが読み飛ばし、s.isna() で位置を調べられます。

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}
ラベルもデータ:重複と打ち間違いアライメントの精度はラベル次第です。"AAPL" と "aapl " は別のラベルなので、打ち間違いは黙って NaN の行を生みます。組み合わせる前にラベルを整えましょう(strip、upper)。インデックスに重複があると s["AAPL"] は値でなく Series を返すので、ラベルごとに値が1つのはずのデータでは s.index.is_unique を確認します。演算は新しい Series を返し、元は変わりません。ラボのテストが確認するのもこの挙動です。
  • pd.Series(values, index=labels, name=...)。ラベルは s["A"]、位置は s.iloc[0] で読む
  • 演算はラベルで揃う(和集合のインデックス、欠けは NaN)。a.add(b, fill_value=0) は欠けを0にする
  • sort_values・abs・idxmax・s / s.iloc[0] * 100。結果は新しい Series で、元は変わらない

次は pandas の DataFrame です。1つのインデックスを共有する Series でできた表です。

ラボ:採点される内容

  • price_series で価格にシンボルのラベルを付ける25点
  • total_exposure で2つの口座をラベルごとに合算する25点
  • top_movers で最も大きく動いた銘柄を見つける25点
  • rebase_to_100 で各価格を100基準にそろえる25点
エクスプローラー · lab-38-1
▾ lab-38-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-38-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

このトピックをリセットしますか?

lab-38-1 の内容はすべてスターターファイルに戻り、ターミナルも消去されます。現在の解答は失われ、元に戻せません。

リセットされるもの
  • main.py → スターターコード
  • ターミナル履歴とテスト出力
  • 未提出の変更
保持されるもの
  • ラボの最高スコア
  • XPと連続日数
  • 講義の進捗とメモ

コードを実行するにはログインしてください。

レクチャーはすべて無料で読めます。コードの実行、テスト、ラボの提出にはアカウントの作成かログインが必要です。

  • ブラウザ内IDEとbashターミナル。インストール不要
  • 即時採点、XP、ロードマップでの現在地
アカウントを作成ログイン
または
GitHubで続ける