从概率矩阵中随机选择

我正在尝试制作一个传入消息的模拟器到输出端口。我得到了输入端口数 (N) 和输出端口数 (M) 以及 N*M (mat) 概率的扁平矩阵。我还以数组(in_freq)的形式给出了传入消息的数量。我想,为了将每条消息从输入端口或输出端口定向,我应该使用 numpy.random.choice,但没有设法使其工作。

我试过的是:

 for k in range (N):  
       enqueue = np.random.choice(M, in_freq[k], p=[(mat[k*N:k*N+M-1])])

当 enqueue 是消息目的地的数组时。

但是遇到了这样的消息:

ValueError:对象对于所需数组来说太深


神不在的星期二
浏览 127回答 1
1回答

尚方宝剑之说

问题在ValueError你所看到的是,作为hpaulj在评论中指出,由于你的p论点被包裹在列表括号[]。这种额外的封闭list使np.random.choice您可以将您解释p为形状的二维数组(1, x)而不是一维数组。由于您的第一个参数 tonp.random.choice是一个整数,因此该函数期望p是一维的,因此当它看到它不是时会抛出错误(有关完整详细信息,请参阅choice文档)。您可以ValueError通过删除周围的括号来解决这个问题p:enqueue = np.random.choice(M, in_freq[k], p=mat[k*N:k*N+M-1])但是,现在您的代码将引发一个新的和不同的ValueError:ValueError: a and p must have same size这ValueError是因为您生成扁平 NxM 矩阵的行切片的mat方式不正确。解决方案从您问题中的描述来看,您的意图似乎是mat通过切片 1D来循环遍历原始 2D 的行mat。这里是你如何解决切片在你的代码,这样你迭代的排mat在你的for循环:import numpy as npN = 10M = 5in_freq = np.random.randint(0, 10, N)mat = np.random.rand(N, M)# normalize so that each row is a probability distmat /= mat.sum(axis=1, keepdims=True)# flatten to match OP's questionmat = mat.flatfor k in range(N):    print((M*k, M*(k + 1)))    enqueue = np.random.choice(M, in_freq[k], p=mat[M*k:M*(k + 1)])测试为了证明现在正在生成正确的切片,我添加了一个打印语句,在循环的每次迭代中输出切片索引for。这是输出:(0, 5)(5, 10)(10, 15)(15, 20)(20, 25)(25, 30)(30, 35)(35, 40)(40, 45)(45, 50)这表明迭代行所需的切片mat现在确实按预期生成。关于将 2D 索引转换为其 1D 平展等效项的注意事项给定一个包含N行和M列的数组,将 2Dx,y索引转换为其扁平化的 1D 等价物的一般公式i是:i = x + M*y您可以在这个旧线程中找到更深入的讨论。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python