首页 > 解决方案 > Julia - 另一个向量重复一个向量的条目(内部)

问题描述

我有一个数组x,我想将每个条目重复x由另一个数组的相应条目指定的次数y,长度相同x

x = [1, 2, 3, 4, 5]    # Array to be repeated
y = [3, 2, 1, 2, 3]    # Repetitions for each element of x
# result should be [1, 1, 1, 2, 2, 3, 4, 4, 5, 5, 5]

有没有办法在 Julia 中做到这一点?

标签: julia

解决方案


您已经在评论中给出了我建议的答案:

vcat(fill.(x, y)...)

这是如何运作的?开始fill

help?> fill

  fill(x, dims::Tuple)
  fill(x, dims...)

  Create an array filled with the value x. For example, fill(1.0, (5,5)) returns a 5×5 array of floats, with each element initialized to 1.0.

这比我们需要的情况要复杂一些(我们只有一个维度要填充),所以让我们看一个简单的例子:

julia> fill(1, 3)
3-element Vector{Int64}:
 1
 1
 1

所以fill(1, 3)只是意味着“取第一个,并将这个数字放入一维数组中 3 次。”

这当然正是我们在这里想要做的:对于 中的每个元素x,我们需要一个数组来多次保存该元素,倍数由 中的相应元素给出y。因此,我们可以循环xy执行以下操作:

julia> for (xᵢ, yᵢ) ∈ zip(x, y)
           fill(xᵢ, yᵢ)
       end

现在这个循环没有返回任何东西,所以我们必须预先分配一些存储空间并在循环中分配给它。在自动返回对象的同时编写此代码的更简洁的方法是理解:

julia> [fill(xᵢ, yᵢ) for (xᵢ, yᵢ) ∈ zip(x, y)]
5-element Vector{Vector{Int64}}:
 [1, 1, 1]
 [2, 2]
 [3]
 [4, 4]
 [5, 5, 5]

更简洁地说,我们可以只使用广播:

julia> fill.(x, y)
5-element Vector{Vector{Int64}}:
 [1, 1, 1]
 [2, 2]
 [3]
 [4, 4]
 [5, 5, 5]

所以从理解或广播中我们得到一个向量的向量,每个向量都是x重复y时间的一个元素。现在剩下的就是通过垂直连接它们将它们放在一个向量中:


julia> vcat(fill.(x, y)...)
11-element Vector{Int64}:
 1
 1
 1
 2
 2
 3
 4
 4
 5
 5
 5

在这里,我们基本上使用splatting来做:

z = fill.(x, y)
vcat(z[1], z[2], z[3], z[4], z[5])

请注意,对于可变长度的数组,飞溅可能具有次优性能,因此更好的方法是使用reduce针对此情况的特殊情况并给出相同的结果:

reduce(vcat, fill.(x, y))

推荐阅读