【问题标题】:Efficiently select random matrix indices with given probabilities有效地选择具有给定概率的随机矩阵索引
【发布时间】:2016-09-24 06:38:50
【问题描述】:

我有一个 numpy 概率数组,例如:

[[0.1,  0,   0.3,],
  0.2,  0,   0.05],
  0,    0.15, 0.2 ]]

我想从这个矩阵中选择一个元素(例如,选择一些索引 (i,j)),概率根据这个矩阵加权。这将使用的实际矩阵很大(高达 1000x1000),所以我正在寻找一种有效的方法来做到这一点。这是我目前的解决方案:

def weighted_mat_choice(prob_mat):
    """
    Randomly select indices of the matrix according to the probabilities in prob_mat
    :param prob_mat: Normalized probabilities to select each element
    :return: indices (i, j) selected
    """
    inds_mat = [[(i, j) for j in xrange(prob_mat.shape[1])] for i in xrange(prob_mat.shape[0])]
    inds_list = [item for sublist in inds_mat for item in sublist]
    inds_of_inds = xrange(len(inds_list))
    prob_list = prob_mat.flatten()
    pick_ind_of_ind = np.random.choice(inds_of_inds, p=prob_list)
    pick_ind = inds_list[pick_ind_of_ind]
    return pick_ind

这绝对没有效率。 (基本上,线性化矩阵,创建索引元组列表,然后相应地进行选择。)有没有更好的方法来进行这种选择?

【问题讨论】:

  • 你的概率矩阵是稀疏的吗?也就是说,大多数值是 0 吗?
  • 没有。实际上,在我的例子中,矩阵的任何元素都不是 0。

标签: python numpy matrix


【解决方案1】:

您不需要选择元组列表。只需使用arange(n) 数组,然后通过unravel_index() 将其转换回二维。

import numpy as np

p = np.array(
[[0.1,  0,   0.3,],
 [0.2,  0,   0.05],
 [0,    0.15, 0.2]]
)

p_flat = p.ravel()
ind = np.arange(len(p_flat))

res = np.column_stack(
    np.unravel_index(
        np.random.choice(ind, p=p_flat, size=10000),
        p.shape))

结果:

array([[0, 2],
       [2, 2],
       [2, 1],
       ..., 
       [1, 0],
       [0, 2],
       [0, 0]], dtype=int64)

【讨论】:

  • 我只想生成 1 个坐标,而不是全部。所以我可以摆脱`size=10000,但如果我只寻找一个而不是全部,那会改变优化它的方式吗?
  • 如果你只需要一个样本,那么不要使用unravel_index(),而是使用i % widthi // width来获取坐标。
猜你喜欢
  • 2019-05-10
  • 2021-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-28
  • 2013-03-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多