通过在Julia中重复一些旧数组来创建一个新数组

时间:2017-01-19 02:37:22

标签: julia

假设我有一个数组:

julia> a = [1 1; 2 2; 3 3; 4 4; 5 5; 6 6; 7 7;]
7×2 Array{Int64,2}:
 1  1
 2  2
 3  3
 4  4
 5  5
 6  6
 7  7

我创建一个向量,指定每行在新数组中重复的次数:

julia> r = [0; 2; 0; 4; 0; 1; 0;]
7-element Array{Int64,1}:
 0
 2
 0
 4
 0
 1
 0

我想要的输出是:

julia> a_repeated = [2 2; 2 2; 4 4; 4 4; 4 4; 4 4; 6 6;]
7×2 Array{Int64,2}:
 2  2
 2  2
 4  4
 4  4
 4  4
 4  4
 6  6

我如何到达那里?我以为我会使用repeat函数,但我似乎无法理解innerouter的工作原理。

2 个答案:

答案 0 :(得分:2)

我们可以使用repeat和数组理解来获得结果:

julia> a[2,:]'
1×2 Array{Int64,2}:
 2  2

# inner=(2,1)
# 2: repeat twice in the first dimension
# 1: don't repeat in the second dimension
julia> repeat(a[2,:]', inner=(2,1)) 
2×2 Array{Int64,2}:          
 2  2
 2  2

# returns empty array
julia> repeat(a[2,:]', inner=(0,1))
0×2 Array{Int64,2}

julia> vcat([repeat(a[i,:]', inner=(r[i],1)) for i in indices(a,1)]...)
7×2 Array{Int64,2}:
 2  2
 2  2
 4  4
 4  4
 4  4
 4  4
 6  6

答案 1 :(得分:2)

使用rep function from DataArrays.jl,这既简单又有效。不过,它在那里被弃用了,所以我把它拉出来并自己定义:

function rep{T <: Integer}(x::AbstractVector, lengths::AbstractVector{T})
    if length(x) != length(lengths)
        throw(DimensionMismatch("vector lengths must match"))
    end
    res = similar(x, sum(lengths))
    i = 1
    for idx in 1:length(x)
        tmp = x[idx]
        for kdx in 1:lengths[idx]
            res[i] = tmp
            i += 1
        end
    end
    return res
end

sample类似,它适用于矢量而不是矩阵,因此我们会像Sample rows from an array in Julia中那样进行同样的歌曲和舞蹈。计算行的索引,然后使用它们索引到矩阵:

julia> idxs = rep(indices(a, 1), r)
7-element Array{Int64,1}:
 2
 2
 4
 4
 4
 4
 6

julia> a[idxs, :]
7×2 Array{Int64,2}:
 2  2
 2  2
 4  4
 4  4
 4  4
 4  4
 6  6