我正在尝试创建将传入消息输出到端口的模拟器。 我得到了输入端口的数量(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])])
当入队消息的目的地数组时。
但是遇到了消息:
ValueError:对象太深,无法放入所需的数组
答案 0 :(得分:1)
正如hpaulj在评论中指出的那样,您看到的ValueError
是由于您的p
参数包装在列表括号[]
中。这种list
的额外包围使np.random.choice
将p
解释为形状为(1, x)
的2D数组,而不是1D数组。由于您对np.random.choice
的第一个参数是整数,因此该函数期望p
为一维,因此在发现不是{D1}时将引发错误(有关详细信息,请参见choice
docs)
您可以通过删除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
的行切片的方式不正确。
从您问题的描述中,您似乎想要通过切片1D mat
来遍历原始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)])
为了证明现在正在生成正确的切片,我添加了一条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中找到更深入的讨论。