σμ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 AcademyRutas
Ctrl K
AO
+1,2 k estudiantes
Iniciar sesiónUnirse ↗
Rutas
AO
+1,2 k estudiantes
Iniciar sesión
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Ruta de Python›Módulo 2 · NumPy y pandas para datos de mercado›Tema 2.6·~45 minPrincipiante

DataFrames de pandas

Posición en la rutaMódulo 2 de 11 · Tema 6 de 20
2.6 DataFrames de pandas
—Puntuación del lab— / 100XP total—Racha—

Una tabla de columnas etiquetadas

Un DataFrame es una tabla bidimensional: un conjunto de columnas, cada una una Series, que comparten un índice de etiquetas de fila. Es el caballo de batalla del análisis de datos de mercado: una fila por símbolo o por día, una columna por campo (precio, volumen, rendimiento). Se construye a partir de un diccionario de columnas, pd.DataFrame({"price": [...], "volume": [...]}, index=symbols), o de una lista de diccionarios de filas. Cada columna tiene su propio dtype (los precios son float64, los volúmenes int64), a diferencia de un arreglo NumPy que tiene un único dtype para todo.

import pandas as pd

df = pd.DataFrame(
    {"price": [184.25, 410.2, 171.0], "volume": [200, 50, 300]},
    index=["AAPL", "MSFT", "GOOG"],
)
print(df)
#        price  volume
# AAPL  184.25     200
# MSFT  410.20      50
# GOOG  171.00     300

print(df.shape, df.columns.tolist())              # (3, 2) ['price', 'volume']
print(df.dtypes.astype(str).to_dict())            # {'price': 'float64', 'volume': 'int64'}

rows = [{"symbol": "AAPL", "price": 184.25}, {"symbol": "MSFT", "price": 410.2}]
print(pd.DataFrame(rows))                         # from a list of row dictionaries
#   symbol   price
# 0   AAPL  184.25
# 1   MSFT  410.20

Columnas, columnas nuevas y filas filtradas

df["price"] es una columna, una Series; df[["price"]] con una lista es un DataFrame de una columna. Una columna nueva sale de aritmética entre columnas: df.assign(notional=df["price"] * df["volume"]) devuelve un marco nuevo con la columna extra y deja df intacto (escribir df["notional"] = ... modifica el propio df). Una condición booleana sobre una columna filtra filas, df[df["volume"] >= 100], y df.sort_values("volume", ascending=False) las ordena, con .head(n) quedándose con las primeras n. Todo esto opera sobre columnas enteras a la vez: no recorras filas con iterrows() cuando existe una operación de columna.

import pandas as pd

df = pd.DataFrame(
    {"price": [184.25, 410.2, 171.0], "volume": [200, 50, 300]},
    index=["AAPL", "MSFT", "GOOG"],
)

bigger = df.assign(notional=df["price"] * df["volume"])   # a new frame
print(bigger)
#        price  volume  notional
# AAPL  184.25     200   36850.0
# MSFT  410.20      50   20510.0
# GOOG  171.00     300   51300.0
print(df.columns.tolist())                                # ['price', 'volume']  df is unchanged

print(df[df["volume"] >= 100])                            # rows that pass the test
#        price  volume
# AAPL  184.25     200
# GOOG  171.00     300

print(df.sort_values("volume", ascending=False).head(2))  # the two biggest volumes
#        price  volume
# GOOG  171.00     300
# AAPL  184.25     200

Resúmenes y una mirada a los datos

Mira siempre una tabla antes de fiarte de ella. df.head() muestra las primeras filas, df.shape da (filas, columnas), df.dtypes lista el tipo de cada columna, df.isna().sum() cuenta los valores ausentes por columna y df.describe() resume las columnas numéricas (cuenta, media, desviación típica, mínimo, cuartiles, máximo). Los métodos de columna como df.mean() dan un valor por columna; df.sum(axis=1) da uno por fila. Un dtype object o str donde esperabas números suele significar que se coló texto en la columna.

import pandas as pd

df = pd.DataFrame(
    {"price": [184.25, 410.2, 171.0], "volume": [200, 50, 300]},
    index=["AAPL", "MSFT", "GOOG"],
)

print(df.describe().loc[["count", "mean", "max"]])
#         price      volume
# count    3.00    3.000000
# mean   255.15  183.333333
# max    410.20  300.000000

print(df.mean().to_dict())                 # {'price': 255.15, 'volume': 183.33333333333334}
print(df.sum(axis=1).tolist())             # [384.25, 460.2, 471.0]   one value per row
print(df.isna().sum().to_dict())           # {'price': 0, 'volume': 0}

# Changing a copy never changes the original (pandas 3 copies on write)
cheap = df[df["price"] < 200].copy()
cheap.loc["AAPL", "price"] = 0.0
print(df.loc["AAPL", "price"])             # 184.25
import pandas as pd

rows = [
    {"symbol": "AAPL", "price": 184.25, "volume": 200},
    {"symbol": "MSFT", "price": 410.2, "volume": 50},
]
df = pd.DataFrame(rows).set_index("symbol")      # make a column the row labels
print(df)
#          price  volume
# symbol
# AAPL    184.25     200
# MSFT    410.20      50

print(df.rename(columns={"price": "px"}).columns.tolist())   # ['px', 'volume']
print(df.drop(columns="volume").columns.tolist())             # ['price']
print(df.reset_index().columns.tolist())                      # ['symbol', 'price', 'volume']
Devuelve marcos nuevos, no edites la tabla de quien llamaUna función que recibe un DataFrame debe tratarlo como de solo lectura y devolver uno nuevo: usa assign, el filtrado booleano y sort_values, que devuelven marcos nuevos. El error clásico es escribir una columna nueva en el argumento, lo que la añade en silencio a la tabla de quien llama. Las pruebas del lab comparan el argumento antes y después justo por eso.
  • pd.DataFrame({columna: valores}, index=labels); df["c"] es una Series, df[["c"]] un DataFrame; cada columna tiene su dtype.
  • assign añade una columna a un marco nuevo; df[máscara] filtra filas; sort_values(...).head(n) toma los n primeros.
  • Mira primero: shape, dtypes, head(), describe(), isna().sum(); nunca edites el marco de quien llama.

A continuación: seleccionar datos con loc e iloc, las dos formas precisas de elegir filas y columnas por etiqueta o por posición.

Lab: qué se califica

  • Construir una tabla de precios y volúmenes con make_frame25 pts
  • Añadir una columna de valor negociado con add_notional25 pts
  • Quedarse solo con las filas líquidas con filter_liquid25 pts
  • Clasificar las filas por cualquier columna con top_by25 pts
Explorador · lab-39-1
▾ lab-39-1
…
bash · en el navegador
learner@quantcraft:~/lab-39-1$
Python aún no cargadoPythonLn 1, Col 1Spaces: 4UTF-8

¿Restablecer este tema?

Todo lo que hay en lab-39-1 vuelve a los archivos iniciales y se limpia el terminal. Tu solución actual se perderá: no se puede deshacer.

Se restablecerá
  • main.py → código inicial
  • Historial del terminal y salida de pruebas
  • Cambios sin enviar
Se conservará
  • Mejor puntuación del lab
  • Tu XP y tu racha
  • Progreso de la lección y notas

Inicia sesión para ejecutar tu código.

Todas las clases se pueden leer gratis. Crea una cuenta o inicia sesión para ejecutar código, lanzar las pruebas y enviar este lab.

  • IDE en el navegador con terminal bash — sin instalar nada
  • Corrección instantánea, XP y tu lugar en la ruta
Crear una cuentaIniciar sesión
O
Continuar con GitHub