Creating an empty 2D array and append values to it

2,107 views
Skip to first unread message

Fred

unread,
Apr 12, 2016, 9:38:11 AM4/12/16
to julia-users
Hi !

The questions I have is so trivial that I spend a long time trying to find an example on the doc and on the web but I did not manage to do exactly what I want :

I want to create an empty 2D array  :  the function readdlm create exactly the kind of array I want if I read a CSV file with 2 columns. For example :

julia> m
1913x2 Array{Float64,2}:
 
201.07     6597.95    
 
202.092   17835.7      
 
202.944    9667.59    
 
204.015   11983.4      
 
204.811    7586.52    
 
205.803       1.1506
....




I tried to create exactly the same type of array and append values to it :

julia> a = Array{Float64,2}
Array{Float64,2}


push
!(a, 10.0,3.0)
ERROR
: MethodError: `push!` has no method matching push!(::Type{Array{Float64,2}}, ::Float64)
Closest candidates are:
  push
!(::Any, ::Any, ::Any)
  push
!(::Any, ::Any, ::Any, ::Any...)
  push
!(::Array{Any,1}, ::ANY)


 push
!(a, [10.0,3.0])
ERROR
: MethodError: `push!` has no method matching push!(::Type{Array{Float64,2}}, ::Array{Float64,1})
Closest candidates are:
  push
!(::Any, ::Any, ::Any)
  push
!(::Any, ::Any, ::Any, ::Any...)
  push
!(::Array{Any,1}, ::ANY)


append
!(a, [10.0,3.0])
ERROR
: MethodError: `append!` has no method matching append!(::Type{Array{Float64,2}}, ::Array{Float64,1})
Closest candidates are:
  append
!{T}(::Array{T,1}, ::AbstractArray{T,1})
  append
!{T}(::StatsBase.AbstractHistogram{T,1,E}, ::AbstractArray{T,1})
  append
!{T}(::StatsBase.AbstractHistogram{T,1,E}, ::AbstractArray{T,1}, ::StatsBase.WeightVec{W,Vec<:AbstractArray{T<:Real,1}})
 
...



etc... I tried every possible syntax to append values to an empty 2D array and I did not find the solution and the correct syntax :)

Thank you for your help !

Yichao Yu

unread,
Apr 12, 2016, 9:44:39 AM4/12/16
to Julia Users
It's not possible without creating a new one.

You can create a 1d one and resize it.

Fred

unread,
Apr 12, 2016, 10:26:48 AM4/12/16
to julia-users
Thank you very much Yichao ! This explain all the problems I have... But it still unclear :

I cannot create an empty 1D array and resize it :

julia> b = Array[]
0-element Array{Array{T,N},1}


julia
> b = Array[]
0-element Array{Array{T,N},1}


julia
> reshape(b,2,2)
ERROR
: DimensionMismatch("new dimensions (2,2) must be consistent with array size 0")
 
in reshape at array.jl:146
 
in reshape at abstractarray.jl:215






if I create a non empty 2D array I still have problems to append values to it :

julia> b = [1 2; 3 4]
2x2 Array{Int64,2}:
 
1  2
 
3  4


julia
> push!(b,[5,6])
ERROR
: MethodError: `push!` has no method matching push!(::Array{Int64,2}, ::Array{Int64,1})


julia
> append!(b,[5,6])
ERROR
: MethodError: `append!` has no method matching append!(::Array{Int64,2}, ::Array{Int64,1})


even if possible, the values 1234 used to create the array will create mistakes in my calculations ;)

The only possibility I found is to create a non empty 1D array :


julia
> c = [1 2 3 4]
1x4 Array{Int64,2}:
 
1  2  3  4


An then reshape it :

julia> reshape(c,2,2)
2x2 Array{Int64,2}:
 
1  3
 
2  4


But that means, that the array c cannot grow in size using push!() , is that true ?

Tim Holy

unread,
Apr 12, 2016, 10:27:50 AM4/12/16
to julia...@googlegroups.com
Note that in `a = Array{Float64,2}`, `a` is a *type*, not an *instance*. You
presumably mean `a = Array(Float64, 0, 0)`.

But Yichao is right that you can't grow a 2d array, only a 1d one.

Best,
--Tim

Fred

unread,
Apr 12, 2016, 10:38:41 AM4/12/16
to julia-users
Thank you very much Tim !

In fact I want to create an X,Y array so if I create a 1D array, I can only append to it (x1,y1) then (x2,y2)... (xn, yn), because I calculate x1 before x2...

julia> d = ["x1", "y1", "x2", "y2", "x3", "y3"]
6-element Array{ASCIIString,1}:
 "x1"
 "y1"
 "x2"
 "y2"
 "x3"
 "y3"

julia> reshape(d,3,2)
3x2 Array{ASCIIString,2}:
 "x1"  "y2"
 "y1"  "x3"
 "x2"  "y3"

you see the problem ? instead I would like to have :
x1 y1
x2 y2
..
xn yn 

because I want to be able to work on columns and line ... of course another easy solution is to use dataframes, but I tried with arrays because the code should be faster... :)

Matt Bauman

unread,
Apr 12, 2016, 10:58:21 AM4/12/16
to julia-users
It'd probably be fastest if you can pre-allocate your array:

A = Array(ASCIIString, 3, 2)
for i=1:size(A, 1)
    A[i, 1] = string('w'+i, 1)
    A[i, 2] = string('w'+i, 2)
end

If you don't know how many elements you'll have, you can use two column vectors, `c1` and `c2`, and push to them independently.  Then horizontally concatenate them together to get your resulting `A = [c1 c2]`.

Yichao Yu

unread,
Apr 12, 2016, 11:06:02 AM4/12/16
to Julia Users
On Tue, Apr 12, 2016 at 10:58 AM, Matt Bauman <mba...@gmail.com> wrote:
> It'd probably be fastest if you can pre-allocate your array:
>
> A = Array(ASCIIString, 3, 2)
> for i=1:size(A, 1)
> A[i, 1] = string('w'+i, 1)
> A[i, 2] = string('w'+i, 2)
> end
>
> If you don't know how many elements you'll have, you can use two column
> vectors, `c1` and `c2`, and push to them independently. Then horizontally
> concatenate them together to get your resulting `A = [c1 c2]`.

I was assuming that the growing is in the continuous direction (i.e.
doesn't require moving all previous elements around) since this is the
case allowing growing a 2D array might make some sense.

If it is not the case then Matt's solution is much better.

Fred

unread,
Apr 12, 2016, 11:08:39 AM4/12/16
to julia-users
Thank you very much Matt. In fact I will work with floats, but the idea to concatenate 2 columns is good !

Fred

unread,
Apr 12, 2016, 4:36:01 PM4/12/16
to julia-users
Thank you ! I think I will use this solution :

julia
> a = []
0-element Array{Any,1}

julia
> b = []
0-element Array{Any,1}

julia
> push!(a, 1)
1-element Array{Any,1}:
 
1

julia
> push!(a, 2)
2-element Array{Any,1}:
 
1
 
2

julia
> a
4-element Array{Any,1}:
 
1
 
2
 
3
 
4

julia
> b
4-element Array{Any,1}:
 
10
 
20
 
30
 
40

julia
> C = [a b]
4x2 Array{Any,2}:
 
1  10
 
2  20
 
3  30
 
4  40



Greg Plowman

unread,
Apr 13, 2016, 4:40:51 AM4/13/16
to julia-users

julia> reshape(d,3,2)
3x2 Array{ASCIIString,2}:
 "x1"  "y2"
 "y1"  "x3"
 "x2"  "y3"

This is because of Julia's column-major ordering.

you see the problem ? instead I would like to have :
x1 y1
x2 y2
..
xn yn 

In this case, you could use:

julia> reshape(d,2,3)'
3x2 Array{ASCIIString,2}:

 "x1"  "y1"
 "x2"  "y2"
 "x3"  "y3"
Reply all
Reply to author
Forward
0 new messages