σμ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.4·~40 分初級

ブロードキャスト

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

形の異なる配列を一緒に扱う

ここまでは同じ形の配列を組み合わせてきました。ブロードキャストは、NumPy がデータをコピーせずに異なる形の配列を組み合わせるための規則です。最も単純なのはスカラーで、a + 10 はすべての要素に10を足します。10 が a の形に引き伸ばされたかのようです。同じ引き伸ばしは配列同士でも働き、3つの数のベクトルを、3列の行列の各行に足せます(列ごとに1つの値)。各列の平均を引く、資産ごとにボラティリティで割る、すべての2点間の差の表を作る、といったことがループなしでできます。

import numpy as np

a = np.array([[1.0, 2.0, 3.0],
              [4.0, 5.0, 6.0]])       # shape (2, 3)

print(a + 10)                          # a scalar is stretched to every element
# [[11. 12. 13.]
#  [14. 15. 16.]]

per_column = np.array([1, 10, 100])    # shape (3,): one value per column
print(a * per_column)
# [[  1.  20. 300.]
#  [  4.  50. 600.]]

print(a - a.mean(axis=0))              # subtract each column's mean
# [[-1.5 -1.5 -1.5]
#  [ 1.5  1.5  1.5]]

規則:形状を右から比べる

NumPy は2つの形状を右から揃えます。各位置で、2つのサイズが等しいか、片方が 1(その場合は引き伸ばされる)か、片方の配列にその次元がない(1として扱う)必要があります。形状 (2, 3) と (3,) は 3 と 3 が合い、欠けた次元が2行に引き伸ばされて成立します。(2, 3) と (2,) は 3 と 2 がぶつかって失敗し、NumPy は ValueError: operands could not be broadcast together を送出します。結果の形状は各位置で大きいほうのサイズになります。

import numpy as np

a = np.ones((2, 3))
print((a + np.ones(3)).shape)        # (2, 3)   3 meets 3

try:
    a + np.ones(2)                   # 3 meets 2: no match
except ValueError as error:
    print(error)                     # operands could not be broadcast together with shapes (2,3) (2,)

# Size 1 stretches: (3, 1) with (1, 4) gives (3, 4)
print((np.ones((3, 1)) + np.ones((1, 4))).shape)   # (3, 4)

列ベクトルとペアの表

形状 (n,) の1次元配列は常に最後の軸に揃うので、行のように振る舞います。行ごとに1つの値を適用するには、形状 (n, 1) の列が必要です。x[:, np.newaxis] または x.reshape(-1, 1) と書きます。列と行を組み合わせると表全体ができます。x[:, None] - x[None, :] はすべての差 x[i] - x[j] の n×n 行列で、corr * vols[:, None] * vols[None, :] は相関行列を共分散行列に変えます。逆のミスにも注意しましょう。形状 (3,) と (3, 1) を足すと、3つの数のベクトルではなく 3×3 の表が黙って得られます。

import numpy as np

x = np.array([1.0, 2.0, 4.0])
print(x[:, np.newaxis].shape, x.reshape(-1, 1).shape, x[None, :].shape)   # (3, 1) (3, 1) (1, 3)

# All pairwise differences x[i] - x[j]
print(x[:, None] - x[None, :])
# [[ 0. -1. -3.]
#  [ 1.  0. -2.]
#  [ 3.  2.  0.]]

# One factor per row needs a column
a = np.array([[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]])
print(a * np.array([1.0, 2.0])[:, None])
# [[ 1.  2.  3.]
#  [ 8. 10. 12.]]

# Correlation matrix to covariance matrix
corr = np.array([[1.0, 0.5], [0.5, 1.0]])
vols = np.array([0.2, 0.3])
print(corr * vols[:, None] * vols[None, :])
# [[0.04 0.03]
#  [0.03 0.09]]

print((np.ones(3) + np.ones((3, 1))).shape)   # (3, 3)  a silent table, not a vector
import numpy as np

# Standardise every column at once: (x - mean) / std, column by column
a = np.array([[1.0, 10.0],
              [2.0, 20.0],
              [3.0, 30.0]])
z = (a - a.mean(axis=0)) / a.std(axis=0)   # (3, 2) - (2,) -> (3, 2), then divided by (2,)
print(z.round(3).tolist())                 # [[-1.225, -1.225], [0.0, 0.0], [1.225, 1.225]]
print(z.mean(axis=0).round(9).tolist())    # [0.0, 0.0]

# keepdims keeps the reduced axis, so the result can be broadcast back by row too
row_share = a / a.sum(axis=1, keepdims=True)
print(row_share.sum(axis=1).tolist())      # [1.0, 1.0, 1.0]
組み合わせる前に形状を表示する形状がたまたま合うとき、ブロードキャストは決して文句を言いません。結果が意図と違っていてもです。配列を組み合わせる前に、形状と期待する結果の形状を書き出し、その後で result.shape を確認しましょう。(n,) のはずが (n, n) になった、長いベクトル2つから何十億要素もの表ができた、というのは、[:, None] の付け忘れか付けすぎの典型的な兆候です。結果はメモリ上に作られるので、10万要素のベクトル2つは100億要素の表になります。
  • 形状は右から揃える。サイズは等しいか1(または欠落)。結果は大きいほう
  • (n,) は行のように振る舞う。列は x[:, None] か x.reshape(-1, 1)
  • 列と行で表になる:x[:, None] - x[None, :]。result.shape を確認し、不一致は ValueError

次は pandas の Series です。各値にラベルが付いた1次元の配列です。

ラボ:採点される内容

  • demean_columns ですべての列を中心化する25点
  • scale_rows で各行に専用の係数を掛ける25点
  • pairwise_differences ですべての差の表を作る25点
  • covariance_from_correlation で相関を共分散に変換する25点
エクスプローラー · lab-37-1
▾ lab-37-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-37-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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