Python 使用Numpy将数组划分为N个不同大小的随机块

Python 使用Numpy将数组划分为N个不同大小的随机块,python,numpy,random,Python,Numpy,Random,使用numpy.array\u拆分,可以将数组拆分为大小相等的块。有没有一种方法可以根据一个列表将其分为若干块 如何将此数组拆分为4个块,每个块由chunk\u size中给出的块大小决定,并由数组中的随机值组成 import numpy as np np.random.seed(13) a = np.arange(20) chunk_size = [10, 5, 3, 2] dist = [np.random.choice(a, c) for c in chunk_size] print(di

使用
numpy.array\u拆分
,可以将数组拆分为大小相等的块。有没有一种方法可以根据一个列表将其分为若干块

如何将此数组拆分为4个块,每个块由
chunk\u size
中给出的块大小决定,并由数组中的随机值组成

import numpy as np
np.random.seed(13)
a = np.arange(20)
chunk_size = [10, 5, 3, 2]
dist = [np.random.choice(a, c) for c in chunk_size]
print(dist)
但正如所料,我得到了多次重复:

[array([18, 16, 10, 16,  6,  2, 12,  3,  2, 14]),
 array([ 5, 13, 10,  9, 11]), array([ 2,  0, 19]), array([19, 11])]
比如说,

  • 16在第一个块中包含两次
  • 10包含在第一和第二块中
使用
np.split
,我得到的答案是:

>>> for s in np.split(a, chunk_size):
...     print(s.shape)
...
(10,)
(0,)
(0,)
(0,)
(18,)
使用
np.random.choice
replace=False
,仍然会给出重复的元素:

import numpy as np
np.random.seed(13)
a = np.arange(20)
chunk_size = [10, 5, 3, 2]
dist = [np.random.choice(a, c, replace=False) for c in chunk_size]
print(dist)
虽然每个区块现在不包含重复项,但它并不阻止第一个区块和第二个区块中同时包含7:

[array([11, 12,  0,  1,  8,  5,  7, 15, 14, 13]),
 array([16,  7, 13,  9, 19]), array([1, 4, 2]), array([15, 12])]
多亏了


确保
a
的每个元素都包含在一个块中的一种方法是首先创建
a
的随机排列,然后用
np.split
将其拆分

为了从
chunk\u size
获得
np.split
的拆分索引数组,您可以使用
np.cumsum

例子 您可以通过省略
chunk\u size
中的最后一个值来避免后面的空数组,因为
a
的大小和前面的值之和暗示了这一点:

>>> np.split(b, np.cumsum(chunk_size[:-1]))  # [10, 5, 3] -- 2 is implied
[array([11, 12,  0,  1,  8,  5,  7, 15, 14, 13]),
 array([ 3, 17,  9,  4,  2]), array([ 6, 19, 10]), array([16, 18])]

为什么要使用np.random?要从原始数组中获取连续块还是随机元素?随机元素,即使是np.split也会提供连续块:-(使用
replace=False
。@Divakar:这是for循环的不同迭代,因此将被替换。这将鼓励您将它们放在一起并发布您自己的答案。@mkrieger1:我不明白我遗漏了什么。您能帮我一下吗?事实上,如果我再考虑一下给出的建议,我认为它不会起作用预期。你能详细说明一下吗?我想我们的想法是从数组中删除为一个区块选取的元素,这样它们就不会在下面的区块中重复。但为此,你必须使用剩余的项目作为下一次迭代的输入,而不是那些选取的项目。我不确定如何更好地解释它,因为我不知道知道你不清楚的确切内容。也许举个例子会有所帮助:假设数组最初是[1,2,3,4,5],并且[2,3]被选为第一个块。然后在下一次迭代中,你必须使用剩余的项[1,4,5]作为输入进行选择。但是这个建议意味着要使用[2,3]作为再次选择的输入。
>>> import numpy as np
>>> np.random.seed(13)
>>> a = np.arange(20)
>>> b = np.random.permutation(a)
>>> b
array([11, 12,  0,  1,  8,  5,  7, 15, 14, 13,
        3, 17,  9,  4,  2,  6, 19, 10, 16, 18])

>>> chunk_size = [10, 5, 3, 2]
>>> np.cumsum(chunk_size)
array([10, 15, 18, 20])

>>> np.split(b, np.cumsum(chunk_size))
[array([11, 12,  0,  1,  8,  5,  7, 15, 14, 13]),
 array([ 3, 17,  9,  4,  2]), array([ 6, 19, 10]), array([16, 18]),
 array([], dtype=int64)]
>>> np.split(b, np.cumsum(chunk_size[:-1]))  # [10, 5, 3] -- 2 is implied
[array([11, 12,  0,  1,  8,  5,  7, 15, 14, 13]),
 array([ 3, 17,  9,  4,  2]), array([ 6, 19, 10]), array([16, 18])]