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

Python循环堆叠一维数组生成指定形状多维数组问题求助

解决回望期权定价中数组堆叠的问题

看起来你在实现回望期权定价的蒙特卡洛模拟时,卡在了把每次路径的价格数组堆叠成多维数组的环节。我来帮你分析问题并给出解决方案:

问题根源

你当前代码里的问题出在total的更新逻辑上:

total = pathwiseminS.copy()
total = np.append([total],[total], axis=0)

每次循环都会把total重置为当前的pathwiseminS副本,然后又把这个数组重复一次堆叠起来。这就导致最终total只保留了最后一次循环的数组重复两次的结果,形状自然是(2,252),而不是你想要的(200,252)。

另外,循环中频繁使用np.append效率很低,因为numpy数组是固定大小的,每次append都会重新分配内存并复制数据。

解决方案

这里提供两种高效且可靠的方法来实现你的需求:

方法1:用列表收集数组,最后统一转换为numpy数组

这是最直观且高效的方式,先把每次生成的pathwiseminS存入列表,最后一次性转换为多维数组:

class pricing_lookback:
    def __init__(self, spot, rate, sigma, time, sims, steps):
        self.spot = spot
        self.rate = rate
        self.sigma = sigma
        self.time = time
        self.sims = sims
        self.steps = steps
        self.dt = self.time / self.steps
    def call_floatingstrike(self):
        simulationS = np.array([])
        simulationSt = np.array([])
        call2 = np.array([])
        total = []  # 初始化空列表,用来收集每个路径的数组
        for j in range(self.sims):
            sT = self.spot
            pathwiseminS = np.array([])
            for i in range(self.steps):
                phi = np.random.normal()
                sT *= np.exp( (self.rate - 0.5 * self.sigma * self.sigma) * self.dt + self.sigma * phi * np.sqrt(self.dt))
                pathwiseminS = np.append(pathwiseminS, sT)
            total.append(pathwiseminS)  # 将当前路径数组加入列表
            call2 = np.append(call2, max(pathwiseminS[self.steps - 1] - self.spot, 0))
            simulationSt = np.append(simulationSt, pathwiseminS[self.steps - 1])
            simulationS = np.append(simulationS, min(pathwiseminS))
        # 将列表转换为numpy数组,形状为(200,252)
        total = np.array(total)
        # 如果需要形状为(252,200),可以转置:
        # total = np.array(total).T
        call = max(np.average(simulationSt) - np.average(simulationS), 0)
        return call, total

方法2:预分配numpy数组,直接赋值

如果你知道最终数组的形状,可以提前分配好内存,然后直接将每个路径的数组赋值到对应位置,效率更高:

class pricing_lookback:
    def __init__(self, spot, rate, sigma, time, sims, steps):
        self.spot = spot
        self.rate = rate
        self.sigma = sigma
        self.time = time
        self.sims = sims
        self.steps = steps
        self.dt = self.time / self.steps
    def call_floatingstrike(self):
        simulationS = np.array([])
        simulationSt = np.array([])
        call2 = np.array([])
        # 预分配形状为(200,252)的数组,类型和路径数组一致
        total = np.empty((self.sims, self.steps), dtype=np.float64)
        for j in range(self.sims):
            sT = self.spot
            pathwiseminS = np.array([])
            for i in range(self.steps):
                phi = np.random.normal()
                sT *= np.exp( (self.rate - 0.5 * self.sigma * self.sigma) * self.dt + self.sigma * phi * np.sqrt(self.dt))
                pathwiseminS = np.append(pathwiseminS, sT)
            total[j] = pathwiseminS  # 将当前路径数组赋值到第j行
            call2 = np.append(call2, max(pathwiseminS[self.steps - 1] - self.spot, 0))
            simulationSt = np.append(simulationSt, pathwiseminS[self.steps - 1])
            simulationS = np.append(simulationS, min(pathwiseminS))
        # 如果需要形状为(252,200),转置即可:
        # total = total.T
        call = max(np.average(simulationSt) - np.average(simulationS), 0)
        return call, total

额外优化建议

  • 内层循环中用np.append生成pathwiseminS也可以优化,比如预分配pathwiseminS = np.empty(self.steps),然后逐个赋值,避免频繁内存操作:
    pathwiseminS = np.empty(self.steps)
    sT = self.spot
    for i in range(self.steps):
        phi = np.random.normal()
        sT *= np.exp( (self.rate - 0.5 * self.sigma * self.sigma) * self.dt + self.sigma * phi * np.sqrt(self.dt))
        pathwiseminS[i] = sT
    
    这样能进一步提升模拟的效率,尤其是当steps很大的时候。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:22:46