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.
1 Like
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)
.
1 Like
I’ve always thought it’d be nice with a method that allowed you to specify size(a, :columns)
(or mean
, sum
, etc.)
1 Like
I have several times wanted a columns(M) function that returned that vector of views.
1 Like
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 But maybe not much is gained by an iterator if it’s already views?
3 Likes
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]
2 Likes
The problem with an iterator is that you can’t do columns(M)[2]
.
1 Like
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)
1 Like
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