You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python:将列表形式的股票模拟数据转为多列或多重索引DataFrame

股票价格模拟与期权指标的DataFrame高效存储方案

问题现状

原代码生成的DataFrame将二维数组(股票路径、Delta值)直接存入单个单元格,无法直接进行后续数据分析、计算操作,需调整存储结构以适配业务需求。

解决方案实现

先补全缺失的股票路径生成函数(几何布朗运动实现),确保代码可运行:

import numpy as np
import pandas as pd
from scipy import stats
from math import exp

def simpath(S0, sigma, ttm, numSteps, numPaths):
    dt = ttm / numSteps
    paths = np.zeros((numSteps, numPaths))
    paths[0] = S0
    for t in range(1, numSteps):
        paths[t] = paths[t-1] * np.exp((r - 0.5 * sigma**2)*dt + sigma*np.sqrt(dt)*np.random.normal(0,1,numPaths))
    return paths

# 修正原期权定价与Delta计算函数的参数一致性问题
def bscall_val(S0, strike, sigma, ttm, rf):
    d1 = (np.log(S0/strike) + 0.5 * np.power(sigma, 2) * ttm )/(sigma * np.power(ttm, 0.5))
    d2 = d1 - sigma * np.power(ttm, 0.5)                                                                 
    bs_call = S0 * stats.norm.cdf(d1, 0, 1) - strike * exp(-rf * ttm) * stats.norm.cdf(d2, 0, 1)
    return bs_call       

def bscall_delta(S0, strike, sigma, ttm, rf):
    d1 = (np.log(S0/strike) + 0.5 * np.power(sigma, 2) * ttm )/(sigma * np.power(ttm, 0.5))
    bscall_delta = stats.norm.cdf(d1, 0, 1)
    return bscall_delta

方案1:将变量分别转为DataFrame后合并

先把股票路径和Delta各自转为带行列索引的DataFrame,再通过标识列合并,形成规整的长表格式。

def sim_results(strike, sigma, ttm, r, numSteps, numPaths, quantity):
    # 生成股票路径
    path = simpath(S0, sigma, ttm, numSteps, numPaths)
    # 计算每一步的剩余期限,确保Delta计算的时间参数准确
    remaining_ttm = ttm - np.arange(numSteps)*(ttm/numSteps)
    # 计算每个时点每个路径的Delta
    delta = bscall_delta(path, strike, sigma, remaining_ttm[:, np.newaxis], r)
    
    # 路径转DataFrame并规整格式
    path_df = pd.DataFrame(path, columns=[f"path_{i}" for i in range(numPaths)])
    path_df["step"] = path_df.index
    path_df = path_df.melt(id_vars="step", var_name="indicator", value_name="value")
    
    # Delta转DataFrame并规整格式
    delta_df = pd.DataFrame(delta, columns=[f"delta_{i}" for i in range(numPaths)])
    delta_df["step"] = delta_df.index
    delta_df = delta_df.melt(id_vars="step", var_name="indicator", value_name="value")
    
    # 合并两个DataFrame
    combined_df = pd.concat([path_df, delta_df], ignore_index=True)
    return combined_df

说明:长表格式适合后续分组统计、可视化操作,可快速筛选指定指标或步数的数据。

方案2:拆分为动态列(列数随路径数变化)

直接将每个路径的股票价格和Delta作为单独列,步数作为行索引,结构直观,适合快速查看单步数据。

def sim_results(strike, sigma, ttm, r, numSteps, numPaths, quantity):
    path = simpath(S0, sigma, ttm, numSteps, numPaths)
    remaining_ttm = ttm - np.arange(numSteps)*(ttm/numSteps)
    delta = bscall_delta(path, strike, sigma, remaining_ttm[:, np.newaxis], r)
    
    # 生成动态列名
    path_cols = [f"path_{i}" for i in range(numPaths)]
    delta_cols = [f"delta_{i}" for i in range(numPaths)]
    
    # 合并路径与Delta数据
    result_df = pd.DataFrame(path, columns=path_cols)
    result_df[delta_cols] = delta
    result_df.index.name = "step"
    
    return result_df

说明:宽表格式可直接查看某一步所有路径的价格与Delta值,列数随numPaths自动调整,操作简单高效。

方案3:多重索引(MultiIndex)存储

使用三层索引(步数、路径编号、指标类型),是最结构化的存储方式,适配复杂多维数据分析需求。

def sim_results(strike, sigma, ttm, r, numSteps, numPaths, quantity):
    path = simpath(S0, sigma, ttm, numSteps, numPaths)
    remaining_ttm = ttm - np.arange(numSteps)*(ttm/numSteps)
    delta = bscall_delta(path, strike, sigma, remaining_ttm[:, np.newaxis], r)
    
    # 创建多层索引
    index = pd.MultiIndex.from_product(
        [range(numSteps), range(numPaths), ["path", "delta"]],
        names=["step", "path_id", "indicator"]
    )
    
    # 扁平化数据并生成DataFrame
    data = np.concatenate([path.flatten(), delta.flatten()])
    result_df = pd.DataFrame(data, index=index, columns=["value"])
    
    return result_df

说明:可通过索引快速筛选指定数据,例如result_df.loc[(5, 1, "delta")]可直接获取第5步第2个路径的Delta值,适合精细化分析场景。


内容的提问来源于stack exchange,提问作者user3654852

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 14:55:16