How do I create vectors from matrix columns?

What is the most simple syntax for extracting a matrix columns into separate vectors?
My matrix is in a text file (with the name data.dat) with 19 columns and 30000 rows , where each row ends with a line feed \n

In principle, say I have this matrix in the text file:

1 2 3 \n
4 5 6 \n
7 8 9 \n

And want the vectors
v1 = [1, 4, 7]
v2 = [2, 5, 8]
v3 = [3, 6, 9]

There might be a neat trick that is simpler, but what about

julia> a = [1 2 3; 4 5 6; 7 8 9];

julia> (v1, v2, v3) = [a[:,x] for x in 1:size(a,1)]
3-element Array{Array{Int64,1},1}:
 [1, 4, 7]
 [2, 5, 8]
 [3, 6, 9]

after creating the matrix (probably using readdlm)?

Thanks,

I solved it by:

file = open("data.dat")
data = readdlm("data.dat")
close(file)

v1 = data[:,1] 
v1 = transpose(v1)

v2 = data[:,2] 
v2 = transpose(v2)

# ... and so forth for all columns

You don’t need the transpose. Just data[:,1] works fine. Also, you don’t need to open or close the file. @anon94023334 's approach works great.

It’s probable that you want views instead of copies:

columns = [view(a, :, i) for i in 1:size(a, 2)]

Also note that you want size(a, 2), rather than size(a, 1).

I’ve always thought it’d be nice with a method that allowed you to specify size(a, :columns) (or mean, sum, etc.)

I have several times wanted a columns(M) function that returned that vector of views.

Or even better, that returned an iterator across the columns which could be collected to form that Vector. That’d actually be fairly easy to implement, I guess :slight_smile: But maybe not much is gained by an iterator if it’s already views?

julia> columns(M) = (view(M, :, i) for i in 1:size(M, 2))
columns (generic function with 1 method)

julia> M = rand(3, 3)
3Ă—3 Array{Float64,2}:
 0.594998  0.565428  0.19341
 0.522016  0.651766  0.39392
 0.652366  0.59112   0.375274

julia> columns(M)
Base.Generator{UnitRange{Int64},##3#4{Array{Float64,2}}}(#3, 1:3)

julia> for i in columns(M)
       println(i)
       end
[0.594998, 0.522016, 0.652366]
[0.565428, 0.651766, 0.59112]
[0.19341, 0.39392, 0.375274]

The problem with an iterator is that you can’t do columns(M)[2].

But maybe it’s all a bit pointless, since these days you can write

ulia> @view M[:, 2]
3-element SubArray{Float64,1,Array{Float64,2},Tuple{Base.Slice{Base.OneTo{Int64}},Int64},true}:
 0.565428
 0.651766
 0.59112

I don’t think it’s pointless - I like for col in columns(M) :slight_smile:

Yes, me too!

I think it could also solve the issue of colwise inplace operations, e.g. https://github.com/JuliaData/DataTables.jl/issues/36 EDIT No that’s silly - because DataFrames have eachcol :blush: