σμ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 AcademyRoteiros
Ctrl K
AO
+1,2 mil alunos
EntrarParticipar ↗
Roteiros
AO
+1,2 mil alunos
Entrar
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Roteiro de Python›Módulo 2 · NumPy e pandas para dados de mercado›Tópico 2.4·~40 minIniciante

Broadcasting

Posição no roteiroMódulo 2 de 11 · Tópico 4 de 20
2.4 Broadcasting
—Nota do lab— / 100XP total—Sequência—

Arrays de formatos diferentes trabalhando juntos

Até aqui combinamos arrays de mesmo formato. O broadcasting é o conjunto de regras que permite ao NumPy combinar arrays de formatos diferentes sem copiar dados. O caso mais simples é um escalar: a + 10 soma 10 a cada elemento, como se 10 tivesse sido esticado ao formato de a. O mesmo esticamento funciona entre arrays: um vetor de três números pode ser somado a cada linha de uma matriz de três colunas, um valor por coluna. É assim que se subtrai a média de cada coluna, se escala cada ativo pela sua volatilidade ou se monta uma tabela de todas as diferenças par a par sem um único laço.

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]]

A regra: compare os formatos a partir da direita

O NumPy alinha os dois formatos a partir da direita. Em cada posição os dois tamanhos devem ser iguais, ou um deles deve ser 1 (e é esticado), ou um dos arrays simplesmente não tem dimensão ali (tratada como 1). Os formatos (2, 3) e (3,) funcionam: 3 encontra 3, e a dimensão que falta é esticada sobre as 2 linhas. Os formatos (2, 3) e (2,) falham, pois 3 encontra 2: o NumPy gera ValueError: operands could not be broadcast together. O formato do resultado toma o maior tamanho em cada posição.

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)

Vetores coluna e tabelas de pares

Um array 1-D de formato (n,) sempre se alinha ao último eixo, então age como uma linha. Para aplicar um valor por linha você precisa de uma coluna de formato (n, 1): escreva x[:, np.newaxis] ou x.reshape(-1, 1). Combinar uma coluna com uma linha monta uma tabela inteira: x[:, None] - x[None, :] é a matriz n×n de todas as diferenças x[i] - x[j], e corr * vols[:, None] * vols[None, :] transforma uma matriz de correlação em uma de covariância. Cuidado com o erro oposto: somar formatos (3,) e (3, 1) dá em silêncio uma tabela 3×3, não um vetor de três números.

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]
Imprima os formatos antes de combinarO broadcasting nunca reclama quando os formatos por acaso se encaixam, mesmo que o resultado não seja o pretendido. Antes de combinar arrays, anote os formatos e o que você espera; depois confira result.shape. Um resultado (n, n) onde se esperava (n,), ou uma tabela de bilhões de entradas a partir de dois vetores longos, é o sinal clássico de um [:, None] faltando ou sobrando. O resultado é construído na memória: dois vetores de 100 000 valores fazem uma tabela de 10 bilhões de entradas.
  • Os formatos se alinham a partir da direita: tamanhos iguais ou 1 (ou ausentes); o resultado toma o maior.
  • (n,) age como uma linha; faça uma coluna com x[:, None] ou x.reshape(-1, 1).
  • Coluna com linha = uma tabela: x[:, None] - x[None, :]; confira result.shape, divergências falham com ValueError.

A seguir: Series do pandas, arrays unidimensionais que carregam um rótulo com cada valor.

Lab: o que é avaliado

  • Centralizar cada coluna com demean_columns25 pts
  • Dar a cada linha o seu fator com scale_rows25 pts
  • Montar a tabela de todas as diferenças com pairwise_differences25 pts
  • Transformar correlações em covariâncias com covariance_from_correlation25 pts
Explorador · lab-37-1
▾ lab-37-1
…
bash · no navegador
learner@quantcraft:~/lab-37-1$
Python ainda não carregadoPythonLn 1, Col 1Spaces: 4UTF-8

Redefinir este tópico?

Tudo em lab-37-1 volta aos arquivos iniciais e o terminal é limpo. Sua solução atual será perdida — isso não pode ser desfeito.

Será redefinido
  • main.py → código inicial
  • Histórico do terminal e saída dos testes
  • Alterações não enviadas
Será mantido
  • Melhor nota do lab
  • Seu XP e sua sequência
  • Progresso da aula e anotações

Entre para executar o seu código.

Todas as aulas são gratuitas para ler. Crie uma conta ou entre para executar código, rodar os testes e enviar este lab.

  • IDE no navegador com terminal bash — nada para instalar
  • Correção instantânea, XP e o seu lugar no roteiro
Criar uma contaEntrar
OU
Continuar com o GitHub