numpy - 使用 np.random.choice 从矩阵中重复采样

numpy - Sample repeatedly from matrix using np.random.choice

我有一个二维数组,其中每一行都是一个方向:

directions = np.array([[ 1, 0],
                       [-1, 0],
                       [ 0, 1],
                       [ 0,-1]])

我想从中采样几行,然后做一个cumsum(模拟随机游走)。最好的方法是使用 np.random.choice。例如,要采样 10 个步骤,请执行以下操作:

np.random.choice(directions, size=(10,1))
# returns 2D array of shape (10,2), where each row is
# randomly sampled from the previous one

当我 运行 这个时,我得到错误:

ValueError: a must be 1-dimensional

现在,我意识到我有一个二维数组,但在这种情况下它不应该像一维数组的一维数组那样工作吗?这不是广播规则的运作方式吗?

所以,我的问题是如何使这个二维数组充当一维数组的一维数组(即 2 个元素列)。

numpy.random.choice 的替代方法是在标准库中使用 random.choice

In [1]: import numpy as np

In [2]: directions = np.array([[1,0],[-1,0],[0,1],[0,-1]])

In [3]: directions
Out[3]: 
array([[ 1,  0],
       [-1,  0],
       [ 0,  1],
       [ 0, -1]])

In [4]: from numpy.random import choice

In [5]: choice(directions)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-5-dd768952d6d1> in <module>()
----> 1 choice(directions)

mtrand.pyx in mtrand.RandomState.choice (numpy/random/mtrand/mtrand.c:10365)()

ValueError: a must be 1-dimensional

In [6]: import random

In [7]: random.choice(directions)
Out[7]: array([ 0, -1])

In [8]: choices = []

In [9]: for i in range(10):
   ...:     choices.append(random.choice(directions))
   ...:     

In [10]: choices
Out[10]: 
[array([1, 0]),
 array([ 0, -1]),
 array([ 0, -1]),
 array([-1,  0]),
 array([1, 0]),
 array([ 0, -1]),
 array([ 0, -1]),
 array([ 0, -1]),
 array([-1,  0]),
 array([1, 0])]

In [11]: 

最简单的方法可能是使用索引。 choice的第一个参数说明如下:

If an ndarray, a random sample is generated from its elements. If an int, the random sample is generated as if a was np.arange(n)

你可以这样做:

directions = np.array([[ 1, 0],
                       [-1, 0],
                       [ 0, 1],
                       [ 0,-1]])
sampleInd = np.random.choice(directions.shape[0], size=(10,))
sample = directions[sampleInd]

请注意,如果您希望结果为二维数组,请将选择输出指定为一维 (10,) 向量而不是 (10, 1),即二维。

现在你随机游走的最终目的地是

destination = np.sum(sample, axis = 0)

参数 axis = 0 是必需的,否则 sum 将把二维 sample 数组中的所有元素相加,而不是分别添加每一列。