制作随机选择从概率矩阵

2024-04-24 10:44:54 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图使一个模拟器的传入消息输出端口。 给出了输入端口数(N)和输出端口数(M)以及N*M(mat)的平坦概率矩阵。我还得到了作为一个数组的传入消息的数量(以\u 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: object too deep for desired array


Tags: 端口in消息for数量矩阵random数组
1条回答
网友
1楼 · 发布于 2024-04-24 10:44:54

问题

正如hpaulj在评论中指出的那样,您看到的ValueError是由于您的p参数被包装在列表括号[]中。这个额外的list使np.random.choicep解释为形状(1, x)的二维数组,而不是一维数组。因为np.random.choice的第一个参数是一个整数,所以函数要求p是1D,当它看到不是1D时抛出一个错误(有关完整的详细信息,请参见^{} docs)。你知道吗

只需删除p周围的括号即可修复ValueError

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不正确造成的。你知道吗

解决方案

从您问题中的描述来看,您的意图似乎是通过切片1Dmat来循环原始2Dmat的行。下面是如何修复代码中的切片,以便迭代for循环中的mat行:

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)])

测试

为了证明现在正在生成正确的切片,我添加了一个print语句,它在for循环的每个迭代中输出切片索引。下面是它的输出:

(0, 5)
(5, 10)
(10, 15)
(15, 20)
(20, 25)
(25, 30)
(30, 35)
(35, 40)
(40, 45)
(45, 50)

这表明遍历mat行所需的片现在确实是按预期生成的。你知道吗

关于将二维索引转换为一维等效索引的注释

给定一个具有N行和M列的数组,将2D x,y索引转换为其平坦的1D等价i的一般公式为:

i = x + M*y

您可以在这个old thread中找到更深入的讨论。你知道吗

相关问题 更多 >