Python 在numpy中洗牌数组的一部分

Python 在numpy中洗牌数组的一部分,python,arrays,numpy,shuffle,Python,Arrays,Numpy,Shuffle,我有一个numpy数组,我想洗牌它的一部分。例如,使用以下数组: import numpy as np import random a = np.arange(15) # => array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]) 我想做: shuffle_parts(a, [(0, 3), (10, 13)]) # => array([ 2, 0, 1, 3, 4, 5, 6, 7,

我有一个numpy数组,我想洗牌它的一部分。例如,使用以下数组:

import numpy as np
import random

a = np.arange(15)
# => array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])
我想做:

shuffle_parts(a, [(0, 3), (10, 13)])
# => array([ 2,  0,  1,  3,  4,  5,  6,  7,  8,  9, 12, 11, 10, 13, 14])
#            ^^^^^^^^^                              ^^^^^^^^^^
#            Shuffle those 3 values                 and those 3 values
以下内容将洗牌所有数组:(不是我想要的)

一种方法是像这样使用拆分/连接:

splits = np.split(a, 5)
random.shuffle(splits[0])
random.shuffle(splits[3])
np.concatenate(splits)
# => array([ 2,  0,  1,  3,  4,  5,  6,  7,  8, 11, 10, 9, 12, 13, 14])
#            ^^^^^^^^^                          ^^^^^^^^^^
#            Correctly shuffled                 Shuffled but off by 1 index
这几乎就是我想要的。我的问题是:

  • 我可以在索引为自定义的位置编写
    shuffle\u parts
    (具有任意索引的部分,不限于模,以及具有不同长度的部分)
  • 在numpy中有没有一种方法是我错过的,可以帮助我做到这一点

可以直接完成:

>>> import numpy as np
>>> import random
>>> a = np.arange(15)
>>> s=3
>>> f=7
>>> random.shuffle(a[s:f])
>>> a
array([ 0,  1,  2,  5,  4,  3,  6,  7,  8,  9, 10, 11, 12, 13, 14])
索引直接引用数据,使之成为可能。

numpy在下面的数据上;因此,您可以直接洗牌切片:

import numpy as np
import random

a = np.arange(15)

random.shuffle(a[0:3])
random.shuffle(a[10:13])
print(a)
# [ 2  0  1  3  4  5  6  7  8  9 12 10 11 13 14]
您可以使用以下方法实现您的
shuffle\u parts
功能:

def shuffle_parts(array, slices):
    for s in slices:
        random.shuffle(a[slice(*s)])

shuffle_parts(array=a, slices=((0, 3), (10, 13)))
或者(取决于您希望如何将切片传递给函数):


就我个人而言,我更喜欢第二个版本(这样你也可以洗牌偶数索引:
shuffle\u部分(array=a,slices=(slice(None,None,2),)
)…

只洗牌数组的切片视图,例如
np.random.shuffle(a[0:3])
我的代码在并行运行的工作程序中运行,我注意到所有随机值最终都是相同的(对于给定的工作批次)。如果我用worker索引初始化随机种子,这就解决了这个问题。我不知道这是否是你所警告的。@BenjaminCrouzier不,随机算法本身是“不安全的”。我认为这对那些只需要一些随机性的程序来说并不重要。我注意到了,以防你想读更多。你混淆了随机性和安全性。Python(扩展名为numpy)使用伪随机数生成器,因此对于加密目的来说它是不安全的。至于其他的事,也没关系。这不是库或语言的弱点或缺点,在任何其他语言中都是一样的。如果你需要真正的随机数,它们必须来自真正的随机源,而不是算法(如果你不知道你是否需要,你就不知道)。@user2699很好,我不想深入到这样的深度,但我认为你的评论的结尾会驱动你的观点——我将编辑掉注释。
def shuffle_parts(array, slices):
    for s in slices:
        random.shuffle(a[slice(*s)])

shuffle_parts(array=a, slices=((0, 3), (10, 13)))
def shuffle_parts(array, slices):
    for s in slices:
        random.shuffle(a[s])

shuffle_parts(array=a, slices=(slice(0, 3), slice(10, 13)))