【问题标题】:shuffle/permutate vector block-wise逐块洗牌/置换向量
【发布时间】:2021-10-05 03:58:37
【问题描述】:

我正在尝试打乱一个简单向量的元素,但我想逐块执行此操作,因此简单的sample 操作不起作用。

我的意思是,每 2 个连续的值都属于一个“块”,我只想打乱块,而不是单个值。

我虽然使用group_by 将我的值组合在一起,但是每个块中的值除了它们一起出现之外没有任何共同点。

这就是示例向量的样子。 (真正的向量有超过 5e6 个元素)。

       <------- BLOCK1 ----->  <----- BLOCK 2 ------>    ........
x <- c(0.15055060, 0.69097695, 0.89731929, 0.84515906, 0.54843043, 0.77026955, 0.05127419, 0.33850021, 0.47623089, 0.36896818)

“成功”的洗牌看起来像这样:

                               <------- BLOCK1 ----->                         <----- BLOCK 2 ------>
x <- c(0.05127419, 0.33850021, 0.15055060, 0.69097695, 0.47623089, 0.36896818, 0.89731929, 0.84515906, 0.54843043, 0.77026955)

非常感谢我如何实现这一点的任何见解!

【问题讨论】:

    标签: r permutation shuffle


    【解决方案1】:

    由于矩阵按列存储在R 中,我们可以简单地将向量转换为行数等于块大小的矩阵。之后,我们需要做的就是打乱矩阵的列并将其转换回向量。这是一个简单的函数:

    ShuffleBlocks <- function(v, size = 2L) {
        size <- as.integer(size)
        stopifnot(length(v) %% size == 0L)
        
        mat <- matrix(v, nrow = size)
        as.vector(mat[, sample(ncol(mat))])
    }
    

    在 OP 的例子中调用它:

    set.seed(42)
    ShuffleBlocks(x)
    # [1] 0.15055060 0.69097695 0.47623089 0.36896818 0.05127419 0.33850021 0.54843043 0.77026955 0.89731929 0.84515906
    #        x[1]       x[2]        x[9]       x[10]      x[7]       x[8]       x[5]       x[6]       x[3]      x[4]
    
    x
    #[1] 0.15055060 0.69097695 0.89731929 0.84515906 0.54843043 0.77026955 0.05127419 0.33850021 0.47623089 0.36896818
    

    这可以平滑地概括为不同的块大小。例如:

    set.seed(321)
    ShuffleBlocks(x, size = 5)
    # [1] 0.77026955 0.05127419 0.33850021 0.47623089 0.36896818 0.15055060 0.69097695 0.89731929 0.84515906 0.54843043 
    

    【讨论】:

      【解决方案2】:

      只打乱区块编号 -

      inds <- sample(length(x)/2) * 2
      x[c(rbind(inds - 1, inds))]
      
      • length(x)/2x 中的块数
      • 我们sample他们并乘以2得到每个块的第二个值
      • 从中减去 - 1 得到第一个块值
      • 将它们组合在一起,并将其用作x 子集的索引。

      任何大小的块的一般解决方案是 -

      n <- 5000 #block size
      inds <- sample(length(x)/n) * n
      x[c(sapply(inds, `-`, (n-1):0))]
      

      【讨论】:

        猜你喜欢
        • 2016-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-10-20
        • 2021-05-04
        • 2020-10-12
        • 1970-01-01
        • 2013-01-15
        相关资源
        最近更新 更多