Reputation: 3545
Suppose I have an array:
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
And I make a vector that specifies how many times each row gets repeated in the new array:
julia> r = [0; 2; 0; 4; 0; 1; 0;]
7-element Array{Int64,1}:
0
2
0
4
0
1
0
The output that I want is:
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
How do I get there? I thought I would use the repeat
function, but I can't seem to understand how inner
and outer
work.
Upvotes: 3
Views: 1473
Reputation: 31342
Using the rep
function from DataArrays.jl, this is simple and efficient. It's deprecated there, though, so I'd pull it out and define it yourself:
function rep(x::AbstractVector, lengths::AbstractVector{T}) where T <: Integer
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
Like sample
, it works on vectors and not matrices, so we do the same song and dance as in Sample rows from an array in Julia. Compute the indices of the rows and then use those to index into the matrix:
julia> idxs = rep(axes(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
Upvotes: 3
Reputation: 8566
we can use repeat
and array comprehension to get the result:
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
Upvotes: 2