根据上一列向右填充 numpy 数组

问题描述 投票:0回答:1

我有以下状态和转移矩阵

import numpy as np

n_states = 3
states = np.arange(n_states)

T = np.array([
    [0.5, 0.5, 0],
    [0.5, 0,  0.5],
    [0,  0,  1]
])

我想模拟

n_sims
路径,其中每条路径由
n_steps
组成。每条路径都从 0 开始。因此,我写

n_sims = 100
n_steps = 10
paths = np.zeros((n_sims, n_steps),  dtype=int)

借助np.random.Generator.choice

帮助
,我想使用过渡矩阵“向右填充”路径。 我的尝试如下

rng = np.random.default_rng(seed=123)

for s in range(1, n_steps+1):
    paths[:,s] = rng.choice(
        a=n_states,
        size=n_sim,
        p=T[paths[:,s-1]]
    )

这会导致以下错误:

ValueError:p 必须是一维的

我该如何克服这个问题?如果可能的话,我想防止 for 循环并对代码进行矢量化。

python numpy
1个回答
0
投票

IIUC,您的过程本质上是迭代的,您不会从 numpy 的矢量化中受益匪浅。

您可能需要考虑使用纯Python:

def simulation(T, n_states=3, n_sims=100, n_steps=10, seed=123):
    rng = np.random.default_rng(seed)
    start = np.zeros(n_steps, dtype=np.int64)
    out = [start]
    for i in range(n_sims-1):
        a = np.array([rng.choice(n_states, p=T[x]) for x in start])
        out.append(a)
        start = a
    return np.array(out)
        
simulation(T, n_states=3, n_sims=100, n_steps=10)

输出示例:

array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [1, 0, 0, 0, 0, 1, 1, 0, 1, 1],
       [2, 0, 1, 0, 1, 2, 2, 0, 2, 2],
       [2, 0, 0, 1, 0, 2, 2, 1, 2, 2],
       [2, 1, 0, 2, 1, 2, 2, 2, 2, 2],
       [2, 2, 0, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 0, 2, 1, 2, 2, 2, 2, 2],
       [2, 2, 1, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 0, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 0, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 1, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 2, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 2, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 2, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 2, 2, 1, 2, 2, 2, 2, 2],
       [2, 2, 2, 2, 0, 2, 2, 2, 2, 2],
       [2, 2, 2, 2, 1, 2, 2, 2, 2, 2],
       [2, 2, 2, 2, 0, 2, 2, 2, 2, 2],
       ...
       [2, 2, 2, 2, 2, 2, 2, 2, 2, 2],
       [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]])
© www.soinside.com 2019 - 2024. All rights reserved.