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] = sTsteps很大的时候。
内容的提问来源于stack exchange,提问作者Varun Yadav
相关产品推荐
相关产品推荐

