为了账号安全,请及时绑定邮箱和手机立即绑定

从概率矩阵中随机选择

从概率矩阵中随机选择

神不在的星期二 2021-09-11 17:56:41
我正在尝试制作一个传入消息的模拟器到输出端口。我得到了输入端口数 (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:对象对于所需数组来说太深
查看完整描述

1 回答

?
尚方宝剑之说

TA贡献1788条经验 获得超4个赞

问题

在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 np


N = 10

M = 5


in_freq = np.random.randint(0, 10, N)

mat = np.random.rand(N, M)

# normalize so that each row is a probability dist

mat /= mat.sum(axis=1, keepdims=True)

# flatten to match OP's question

mat = mat.flat


for 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

您可以在这个旧线程中找到更深入的讨论。


查看完整回答
反对 回复 2021-09-11
  • 1 回答
  • 0 关注
  • 126 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信