【问题标题】:Shuffle part of array in numpy在numpy中随机播放数组的一部分
【发布时间】:2019-03-12 13:30:01
【问题描述】:

我有一个 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

以下内容将对所有数组进行洗牌:(不是我想要的)

random.shuffle(a) 
# => array([10, 11,  8,  1, 13,  5,  9, 14,  4,  7,  2, 12,  3,  0,  6])

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

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_parts,其中索引是自定义的(具有任意索引的部分,不限于模数,以及长度可变的部分)
  • numpy 中是否有我错过的方法可以帮助我做到这一点?

【问题讨论】:

  • 只是随机播放数组的切片视图,例如np.random.shuffle(a[0:3])

标签: python arrays numpy shuffle


【解决方案1】:

可以直接做:

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

索引直接引用数据,使这成为可能。

【讨论】:

  • 我的代码在并行运行的工作人员中运行,我注意到所有随机值最终都相同(对于给定的工作批次)。如果我用工人索引初始化随机种子,就可以解决这个问题。我不知道这是否是您所警告的。
  • @BenjaminCrouzier 不,随机算法本身是“不安全的”。我认为这对于只需要一些随机性的程序来说并不重要。我记下了,以防您想了解更多信息。
  • 您混淆了随机性和安全性。 Python(以及扩展名 numpy)使用伪随机数生成器,因此对于加密目的来说它是不安全的。对于其他任何事情,它都很好。这不是库或语言的弱点或缺点 - 在任何其他语言中都是一样的。如果您需要真正的随机数,它们必须来自真正的随机来源,而不是算法(如果您不知道自己是否需要,那么您不知道)。
  • @user2699 很好,我不想深入探讨,但我认为您的评论结束了您的观点 - 我将编辑注释。
【解决方案2】:

numpy slices are views 在下面的数据上;所以你可以直接洗牌:

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]

您可以使用slice 实现您的shuffle_parts 函数,然后:

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

我个人更喜欢第二个版本(这样你也可以洗牌偶数索引:shuffle_parts(array=a, slices=(slice(None, None, 2), )))...

【讨论】:

    猜你喜欢
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-03
    • 1970-01-01
    • 1970-01-01
    • 2021-07-03
    • 2016-07-16
    相关资源
    最近更新 更多