python 在for循环中追加到numpy数组

wn9m85ua  于 2023-02-07  发布在  Python
关注(0)|答案(1)|浏览(227)

我正在尝试创建一个蒙特卡罗模拟来模拟未来的股票价格使用Numpy数组。
我目前的做法是:创建一个For循环,用模拟的股票价格填充一个数组stock_price_array。这些股票价格是通过取最后一个股票价格,然后乘以1 +年回报率生成的。年回报率是从正态分布中随机抽取的,并存储在数组annual_ret中。
我的问题是,虽然我从For循环打印的“股票价格”变量看起来是正确的,但我就是不知道如何将这些股票价格变量追加到stock_price_array。
我尝试了各种方法,包括使用.full而不是.empty初始化stock_price_array,更改数组在For循环中出现的顺序,以及检查数组的大小。
我读过其他关于堆栈溢出的类似主题的帖子,但不知道我做错了什么。
提前感谢您的帮助!

annual_mean = .06
annual_stdev = .15
start_stock_price = 100

numYears = 3
numSimulations = 4
stock_price_array = np.empty(numYears)

# draw an annual return from a normal distribution; this annual return will be random
annual_ret = np.random.normal(annual_mean, annual_stdev, numSimulations)

for i in range(numYears):
    stock_price = np.multiply(start_stock_price, (1 + annual_ret[i]))
    np.append(stock_price_array, [stock_price])
    start_stock_price = stock_price
63lcw9qa

63lcw9qa1#

numpy 第一条规则是:永远不要自己迭代你的数组。2使用numpy函数,它可以批量完成所有的计算(当然,为了这样做,他们会迭代数组。3但是这种迭代不是python的迭代,所以它要快得多)。

否-溶液

例如,在这里,你可以这样做

np.cumprod(np.hstack([start_stock_price, annual_ret+1]))

它首先构建一个包含初始值和一些因子的数组,如果初始值是100,利率是0.1,-0.1,0.2,0.2(举例来说),那么hstack构建一个值数组。
cumprod只是构建这些的累积乘积
100, 100×1.1=110, 100×1.1×0.9=110×0.9=99, 100×1.1×0.9×1.2=99×1.2=118.8, 100×1.1×0.9×1.2×1.2=118.8×1.2=142.56

你的更正

无论如何,要回答您最初的问题(即使我强烈建议您尝试使用像我所展示的cumprod那样的解决方案),您有两种选择:

  • 或者你预先分配一个数组,就像你所做的那样(你的stock_price_array = np.empty(numYears)),然后,不要试图把新的stock_price追加到stock_price_array,你应该简单地填充其中一个已经存在的空位。
  • 或者不这样做,然后将np.empty行替换为stock_price_array=[],然后在每一步都追加结果以创建新的stock_price_array,如stock_price_array = np.append(stock_price_array, [stock_price])

我强烈反对第二种解决方案。既然你已经知道了数组的最终大小,最好一次创建它。因为np.append重新创建了一个全新的数组,然后将输入数据复制到其中。它不仅仅是扩展了现有的数组(一般来说,我们不能这样做)。
但是,无论如何,我建议不要使用这两种解决方案,因为我发现我的(使用cumprod)更可取。for是numpy中的禁忌词。当在this中创建一个新数组时,就更是如此,就像append一样。
蒙特-卡罗
既然你提到了蒙特-卡罗,然后展示了一个只计算一个结果的代码(你画了一套年回报,计算了一次未来值),我想知道这是不是你想要的,特别是我看到你有numSimulationnumYears,在代码中似乎扮演了多余的角色(因此在矿井中也是如此)。它不只是抛出索引错误的唯一原因是,是因为numSimulation只用来决定你画了多少个annual_ret,而且由于numSimulation > numYears,你有足够的annual_ret来计算结果。
你最初的意图不是要在几年的时间里重做模拟,得到numSimulation的结果吗?
在这种情况下,你可能需要numYears年利率的numSimulation集合,所以是一个2D数组,同样,你应该计算numYears结果的numSimulation系列。
如果我的猜测不是完全错误的话,我推测你真正想做的是:

annual_ret = np.random.normal(annual_mean, annual_stdev, (numSimulations, numYears)) # 2d array of interest rate. 1 simulation per row, 1 year per column

t = np.pad(annual_ret+1, ((0,0), (1,0)), constant_values=start_stock_price) # Add 1 as we did earlier. And pad with an initial 100 (`start_stock_price`) at the beginning of each simulation

res = np.cumprod(t, axis=1) # cumulative multiplication. `axis=1` means that it is done along axis 1 (along years) for each row (for each simulation)

相关问题