将列表拆分为 n 个随机大小的块

Split a list into n randomly sized chunks

我正在尝试将一个列表拆分为 n 个子列表,其中每个子列表的大小是随机的(至少有一个条目;假设 P>I)。我使用了 numpy.split 函数,它工作正常但不满足我的随机性条件。您可能会问随机性应该遵循哪个分布。我想,应该没有关系。我检查了几个与我的 post 不同的 post,因为它们试图用几乎相同大小的块进行拆分。如果重复,请告诉我。这是我的方法:

import numpy as np

P = 10
I = 5
mylist = range(1, P + 1)
[list(x) for x in np.split(np.array(mylist), I)]

P 不能被 I 整除时,此方法失效。此外,它创建大小相等的块,而不是概率大小的块。另一个限制:我不想使用包 random 但我可以使用 numpy。不要问我为什么;我希望我对此有一个合乎逻辑的回应。

根据疯狂科学家提供的答案,这是我试过的代码:

P = 10
I = 5

data = np.arange(P) + 1
indices = np.arange(1, P)
np.random.shuffle(indices)
indices = indices[:I - 1]
result = np.split(data, indices)
result

输出:

[array([1, 2]),
 array([3, 4, 5, 6]),
 array([], dtype=int32),
 array([4, 5, 6, 7, 8, 9]),
 array([10])]

np.split 还是要走的路。如果您传入一个整数序列,split 会将它们视为分割点。生成随机切点很容易。你可以做类似

的事情
P = 10
I = 5

data = np.arange(P) + 1
indices = np.random.randint(P, size=I - 1)

您想要 I - 1 个切分点以获得 I 个区块。需要对索引进行排序,并且需要删除重复项。 np.unique 两者都为您服务。这样你可能会得到少于 I 个块:

result = np.split(data, indices)

如果您绝对需要 I 个数字,请选择不重新采样。例如可以通过 np.shuffle:

来实现
indices = np.arange(1, P)
np.random.shuffle(indices)
indices = indices[:I - 1]
indices.sort()

问题可以重构为从 {1,2,...,P-1} 中选择 I-1 个随机分割点,可以使用 stars and bars.

查看

因此可以这样实现:

import numpy as np

split_points = np.random.choice(P - 2, I - 1, replace=False) + 1
split_points.sort()
result = np.split(data, split_points)