How do I append row vectors into an array when I don't know the exact dimension of the array before calculations end?

I’m using a while statement to carry out calculations for as long as a condition holds. At every iteration, I calculate a vector v. I want to append every new v vector as a row vector to the previous v vector.

The problem is that my condition doesn’t have a fixed number of iterations. With every new data point, the condition can change and the size of myArray will change. I have tried creating an array of type Any; one item in v has a different type String while all other items have type Float64.

I don’t know how many iterations will take for the while loop to stop, therefore I don’t know the number of rows of my array. Because of size difference, I get an error when I try to append v to myArray.

I have tried different variations of vcat and hcat, either transposing v or not — none worked. The following piece of code explains what I’m trying to do with simpler objects.

myArray = [];
myNumber = rand(1)*100;

while myNumber > 0 
   # Compute vector v
   v = ["a", 1, 2, 3]
   # ..............................................
   # Assign v to myArray as a row vector 
   # in every iteration.  How do I do this?
   # ..............................................
   myNumber = myNumber - 1
end

All help is appreciated.

P.S.: At one point, I created A = Array{Any}(undef, n,4), with n large enough that it wouldn’t be a problem. At every iteration, I incremented a counter i and assigned the freshly computed v to row i, A[i,:] = v. The problem with that, besides the many unused rows, is that I tried to subset from A the part that only contained data I wanted. I relied on the type in the columns as a parameter to filter for, but I couldn’t make it work either.

You could use a vector of tuples? I am assuming that you know the size of the records you would be appending?

In [1]: a = Vector{NTuple{3, Float64}}()
Out[1]: Tuple{Float64, Float64, Float64}[]

In [2]: for i ∈ 1:4
             push!(a, (rand(), rand(), rand()))
         end

In [3]: a
Out[3]: 4-element Vector{Tuple{Float64, Float64, Float64}}:
 (0.5245041461916572, 0.556349994815155, 0.9146538258170984)
 (0.07877443211157664, 0.5609529419162536, 0.7461623172366005)
 (0.5086419102034306, 0.1830715697795372, 0.6984704005092253)
 (0.060321039676802024, 0.8323461219441477, 0.1747723930534809)
1 Like

Hi, frylock

Thanks for your answer. I imagine I could insert different types inside of the Tuple, so that could be a way out. But from the output, it seems that in the end you don’t have an array you could subset from, so using the push! command wouldn’t work in the way your presented. I’ll look into it, though. Maybe I can adapt it to what I need.

Thank you.

julia> myArray = [];

julia> myNumber = trunc(Int,(rand(1)*10)[1])
3

julia> while myNumber > 0
          # Compute vector v
          v = ["a", 1, 2, 3]
          # ..............................................
          # Assign v to myArray as a row vector 
          # in every iteration.  How do I do this?
          # ..............................................
          push!(myArray,v)
          myNumber = myNumber - 1
       end

julia> myArray
3-element Vector{Any}:
 Any["a", 1, 2, 3]
 Any["a", 1, 2, 3]
 Any["a", 1, 2, 3]

But maybe you want to get this?
the expected result is not very clear.

julia> stack(myArray,dims=1)
5×4 Matrix{Any}:
 "a"  1  2  3
 "a"  1  2  3
 "a"  1  2  3
 "a"  1  2  3
 "a"  1  2  3

or

julia> permutedims(reduce(hcat,myArray))
5×4 Matrix{Any}:
 "a"  1  2  3
 "a"  1  2  3
 "a"  1  2  3
 "a"  1  2  3
 "a"  1  2  3
1 Like

You may be looking for concatenation. Look into the cat functions, and its various flavors, like hcat or vcat:
Arrays · The Julia Language

A few more things:

  • Consider appending your data as columns, not rows. This should be more efficient.
  • myArray = [] creates a vector, not a matrix.
  • Arrays with mixed types are not terribly efficient. Using a vector of tuples, as suggested above, may be better. Or perhaps store the strings and the numbers separately.
1 Like