How to convert a Matrix into a Vector of Vectors?
Asked Answered
B

4

7

I have the following matrix A = [1.00 2.00; 3.00 4.00] and I need to convert it into a vector of Vectors as follows:

A1 = [1.00; 3.00] A2 = [2.00; 4.00]

Any ideas?

Bathysphere answered 8/8, 2016 at 15:37 Comment(2)
Do you want a vector of vectors or separate objects for each vector? Your text indicators the former, your code illustration indicates the latter.Adjunct
Also, can you give context on why you would need this? In almost every case I can think of, you'd be better just referencing the columns while they are still in your matrix or at most, creating separate views of them with sub(), e.g. B = sub(A, 1:size(A,2),1).Adjunct
K
14

tl;dr
This can be very elegantly created with a list comprehension:

A = [A[:,i] for i in 1:size(A,2)]


Explanation:

This essentially converts A from something that would be indexed as A[1,2] to something that would be indexed as A[2][1], which is what you asked.

Here I'm assigning directly back to A, which seems to me what you had in mind. But, only do this if the code is unambiguous! It's generally not a good idea to have same-named variables that represent different things at different points in the code.

NOTE: if this reversal of row / column order in the indexing isn't the order you had in mind, and you'd prefer A[1,2] to be indexed as A[1][2], then perform your list comprehension 'per row' instead, i.e.

A = [A[i,:] for i in 1:size(A,1)]
Khufu answered 8/8, 2016 at 17:49 Comment(0)
G
4

It's even simpler.

eachcol is all you need. It's an abstract vector.

A=eachcol(A)

Now A[1] is [1.00; 3.00], and A[2] is [2.00; 4.00].

With this approach, there are no memory allocations. Everything is based on views.

Gianina answered 25/8, 2023 at 23:29 Comment(0)
J
2

Another option is B = [eachcol(A)...]. This returns an variable with type Vector{SubArray} which might be fine depending on what you want to do. To get a Vector{Vector{Float64}} try,

B = Vector{eltype(A)}[eachcol(A)...]
Jasso answered 19/7, 2022 at 15:24 Comment(0)
E
1

It would be much better simply to use slices of your matrix i.e. instead of A1 use A[:,1] and instead of A2 use A[:,2]

If you really need them to be "seperate" objections you could try creating a cell array like so:

myfirstcell = cell(size(A,2)) for i in 1:size(A,2) myfirstcell[i] = A[:,i] end

See http://docs.julialang.org/en/release-0.4/stdlib/arrays/#Base.cell

(Cell arrays allow several different types of object to be stored in the same array)

Extortionate answered 8/8, 2016 at 16:49 Comment(2)
You could at least have an Array of Arrays explicitly, without needing to use cell A_vec = Array{Array{eltype(A),1}, size(A,2)}Adjunct
Agreed, the accepted answer is still much better though!Extortionate

© 2022 - 2024 — McMap. All rights reserved.