多列pandas时间序列蒙特卡洛模拟正态样本生成报错解决
报错根因
形状不匹配错误来自三个写法问题:
- 给
loc、scale参数多套了一层方括号,把原本形状为(列数,)的一维均值、标准差数组转成了形状为(1,1,列数)的三维数组 - 手动指定的
size参数是二维,和三维的分布参数无法广播对齐 - 将
diffs.describe()的统计结果赋值给data变量,覆盖了原始时序数据的变量,后续容易引发逻辑错误
正确实现代码
直接提取每列收益率的均值、标准差为一维数组,numpy会自动按列广播生成对应正态分布的样本,最后转成DataFrame方便后续统计:
import numpy as np import pandas as pd # 计算简单收益率(几何布朗运动的增量项) returns = (data.diff() / data.shift(1)).dropna() # 提取各列统计量,输出为一维数组 col_means = returns.mean().to_numpy() col_stds = returns.std().to_numpy() desired_samples = 1000 # 生成随机样本,形状自动对齐为 (样本数, 列数) rng = np.random.default_rng() sample_arr = rng.normal(loc=col_means, scale=col_stds, size=(desired_samples, len(returns.columns))) # 转为和原数据列名一致的DataFrame sample_df = pd.DataFrame(sample_arr, columns=returns.columns)
结果校验
对sample_df执行sample_df.describe()即可得到符合要求的输出:
- 每列count固定为1000
- 各列mean、std和原收益率序列的统计值在随机误差范围内匹配
如果需要统计值完全精确相等(无采样误差),可以在生成后做一次强制标准化校准:
# 校准到精确的给定均值、标准差 sample_df = (sample_df - sample_df.mean()) / sample_df.std() * col_stds + col_means
校准后再调用describe()得到的均值、标准差会和原数据统计值完全一致,适合对参数精度要求极高的蒙特卡洛模拟场景。
内容的提问来源于stack exchange,提问作者Pedro Montoto García
相关产品推荐
相关产品推荐

