Add vector as row to matrix in Julia - julia

I have a vector and a matrix (Array{T,1} and Array{T,2}) in my Julia code and I would like to append them such that the vector becomes a new row in the matrix (should be first row). I've tried several methods (cat, etc.) but keep getting errors which I believe are related to the different shape of the data. See the example below.
julia> v = Vector([1, 2, 3])
3-element Array{Int64,1}:
1
2
3
julia> m = Matrix([4 5 6; 7 8 9])
2×3 Array{Int64,2}:
4 5 6
7 8 9
julia> cat(v,m,dims=(1,2))
5×4 Array{Int64,2}:
1 0 0 0
2 0 0 0
3 0 0 0
0 4 5 6
0 7 8 9
What I actually want is
1 2 3
4 5 6
7 8 9
I realize that I can get this to work with transpose(v) but I was hoping to avoid extra calls.
Thanks!

As long as you can change the construction of v to a 1 x 3 array, you can avoid the transpose:
julia> v = [1 2 3]
1×3 Array{Int64,2}:
1 2 3
julia> m = [4 5 6; 7 8 9]
2×3 Array{Int64,2}:
4 5 6
7 8 9
julia> vcat(v, m)
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
I think that just doing the transpose
julia> v2 = [1, 2, 3]
3-element Array{Int64,1}:
1
2
3
julia> vcat(v2', m)
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
is almost as efficient though.

Related

Julia problems with end, matrix

When I type this error jumps in julia but I don't know why, it should be working./
julia> A = [1 2 3 4; 5 6 7 8; 1 2 3 4; 5 6 7 8]
4×4 Array{Int64,2}:
1 2 3 4
5 6 7 8
1 2 3 4
5 6 7 8
julia> B = A[2:1:end; 2:1:end]
ERROR: syntax: missing last argument in "2:1:" range expression
Stacktrace:
[1] top-level scope at REPL[9]:0
The syntax to index a multidimensional array uses a comma , instead of semicolon ; as separator between dimensions, see https://docs.julialang.org/en/v1/manual/arrays/#man-array-indexing-1. Thus you want to do:
julia> A = [1 2 3 4; 5 6 7 8; 1 2 3 4; 5 6 7 8]
4×4 Array{Int64,2}:
1 2 3 4
5 6 7 8
1 2 3 4
5 6 7 8
julia> B = A[2:1:end, 2:1:end]
3×3 Array{Int64,2}:
6 7 8
2 3 4
6 7 8
Note also that you can omit 1 in the range specification, as step 1 is the default:
julia> A[2:end, 2:end]
3×3 Array{Int64,2}:
6 7 8
2 3 4
6 7 8

Julia comprehension: convert a 2d array of matrices to a 2d matrix

I'm using Julia comprehension to achieve the following:
Given a matrix
A = [1 2; 3 4],
I want to expand it into
B =
[1, 1, 1, 2, 2;
1, 1, 1, 2, 2;
1, 1, 1, 2, 2;
3, 3, 3, 4, 4;
3, 3, 3, 4, 4].
Right now I'm doing this with
ns = [3, 2]
B = [fill(B[i, j], ns[i], ns[j]) for i = 1:2, j = 1:2]
However, instead of getting a 5x5 matrix, it gives me:
2×2 Array{Array{Int64,2},2}:
[0 0 0; 0 0 0; 0 0 0] [0 0; 0 0; 0 0]
[0 0 0; 0 0 0] [0 0; 0 0]
So how should I convert this 2d array of matrices to a 2d matrix? Or are there other ways to do the expansion I need?
Here are two example ways how you could do it (the first one uses your approach, the second one does not generate intermediate matrices):
julia> A = [1 2; 3 4]
2×2 Array{Int64,2}:
1 2
3 4
julia> ns = [3, 2]
2-element Array{Int64,1}:
3
2
julia> hvcat(2, [fill(A[j, i], ns[j], ns[i]) for i = 1:2, j = 1:2]...)
5×5 Array{Int64,2}:
1 1 1 2 2
1 1 1 2 2
1 1 1 2 2
3 3 3 4 4
3 3 3 4 4
julia> nsexpand = reduce(vcat, (fill(k, ns[k]) for k in axes(ns, 1)))
5-element Array{Int64,1}:
1
1
1
2
2
julia> [A[i, j] for i in nsexpand, j in nsexpand]
5×5 Array{Int64,2}:
1 1 1 2 2
1 1 1 2 2
1 1 1 2 2
3 3 3 4 4
3 3 3 4 4
EDIT
Here is an additional example:
julia> A = [1 4 7 10
2 5 8 11
3 6 9 12]
3×4 Array{Int64,2}:
1 4 7 10
2 5 8 11
3 6 9 12
julia> hvcat(3, A...)
4×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
10 11 12
julia> vec(A)
12-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10
11
12
So:
the first argument tells you how how many columns you want to produce
hvcat has h before v so it takes elements row-wise
however arrays store columns col-wise
so in effect you have to create the temporary array as a transpose of your target (because hvcat will take its columns to create rows of a target arrays). Actually this is only a coincidence - hvcat does not know that your original elements were storing in a matrix (it takes them as positional arguments to the call and at that time the fact that they were stored in a matrix is lost due to ... operation).

Make a matrix of matrices

I want to have a matrix whose elements are matrices too.
For example
A=[[1 2 3;3 4 1;2 3 6] [1 4 5;4 8 7;2 0 1];[1 5 8;6 4 7;2 0 0] [2 1 5;4 7 7;2 4 6]]
How can I make this matrix in Julia?
A = first.([([1 2 3;3 4 1;2 3 6],) ([1 4 5;4 8 7;2 0 1],);
([1 5 8;6 4 7;2 0 0],) ([2 1 5;4 7 7;2 4 6],)])
works (on Julia 0.6). Making elements tuples stops the fusing of the submatrices and then first. untuples them.
I'm not sure about a shorthand / literal, but you can construct it and then populate it:
B=Matrix{Matrix}(3,3)
Out[4]:
3×3 Array{Array{T,2} where T,2}:
#undef #undef #undef
#undef #undef #undef
#undef #undef #undef
B[1,1]=[1 2 ; 3 4]
B
Out[8]:
3×3 Array{Array{T,2} where T,2}:
[1 2; 3 4] #undef #undef
#undef #undef #undef
#undef #undef #undef
I don't know why Julia has this (from my POV strange) property:
julia> [1 2 [3 4]]
1×4 Array{Int64,2}:
1 2 3 4
But we could use it to make this trick:
julia> A=[[[1 2 3;3 4 1;2 3 6]] [[1 4 5;4 8 7;2 0 1]];
[[1 5 8;6 4 7;2 0 0]] [[2 1 5;4 7 7;2 4 6]]]
Another strange possibility is (be aware that it is visually transposed!):
julia> A=hcat([[1 2 3;3 4 1;2 3 6], [2 1 5;4 7 7;2 4 6]],
[[1 4 5;4 8 7;2 0 1], [1 5 8;6 4 7;2 0 0]])
or (this needs to be visually transposed too!)
julia> A=reshape([[1 2 3;3 4 1;2 3 6], [2 1 5;4 7 7;2 4 6],
[1 4 5;4 8 7;2 0 1], [1 5 8;6 4 7;2 0 0],],
(2,2))
Edit:
Ad your additional question - you could create Array of desired length and then use reshape:
U = reshape(Matrix{Float64}[zeros(8, 5) for i in 1:20*20], (20,20));
You can create an empty matrix of the aformentioned dimensions first by :
X = zeros(Int64, (3, 3,4))
You can further assign each matrix accordingly:
X[:,:,1] = [1 2 3;3 4 1;2 3 6]
X[:,:,2] = [1 4 5;4 8 7;2 0 1]
X[:,:,3] = [1 5 8;6 4 7;2 0 0]
X[:,:,4] = [2 1 5;4 7 7;2 4 6]
And the matrix X is :
julia > X
julia > 3×3×4 Array{Int64,3}:
[:, :, 1] =
1 2 3
3 4 1
2 3 6
[:, :, 2] =
1 4 5
4 8 7
2 0 1
[:, :, 3] =
1 5 8
6 4 7
2 0 0
[:, :, 4] =
2 1 5
4 7 7
2 4 6
An easier thing to do is to read every element as is by a vector and reshape it.
x = [1,2,3,3,4,1,2,3,6,1,4,5,4,8,7,2,0,1,1,5,8,6,4,7,2,0,0,2,1,5,4,7,7,2,4,6]
x = reshape(x, (3, 3, 4))
This will result in 4 matrices that need a transpose, so for that you can use the permutedims as folows to change the order of the first and second dimensions(each matrix):
permutedims(x,(2,1,3))

How to delete a specific row in Julia

How can I delete a specific row in Julia? Let's say I have an array:
[A , 2
B , 4
C , 6]
I want to delete the lines for which 'B' is in the first column. I can identify which row this is, but am not able to delete this row. Can anybody help me?
Thanks,
Nico
julia> a = rand(1:10, 5,3)
5×3 Array{Int64,2}:
4 5 7
8 4 3
8 6 3
10 4 1
9 3 10
To delete row 4:
julia> row = 4
julia> a = a[setdiff(1:end, row), :]
4×3 Array{Int64,2}:
4 5 7
8 4 3
8 6 3
9 3 10
Say you have a dataframe called "data".
julia> data=DataFrame(rand(1:10, 5,3))
5×3 DataFrames.DataFrame
Row x1 x2 x3
1 9 1 1
2 8 5 8
3 9 2 2
4 9 6 5
5 3 8 7
You want to delete entire row where column x1 has value 8.
julia> data[data[:x1].!=8,:]
4×3 DataFrames.DataFrame
Row x1 x2 x3
1 9 1 1
2 9 2 2
3 9 6 5
4 3 8 7

count frequency of vector elements

I have this code which gives the number of occurrences of each element of w vector in vector y
a= [7 4 9 6 4 10 9 6 7 6]
y=zeros(size(a));
for i=1:length(a)
y(i)=sum(a==a(i));
end
y = y;
end
y=[2 2 2 3 2 1 2 3 2 3]
but this result is not enough because I need to know the index along with the number of repartitions. The result should look like:
element no of repartitions position1 position2 position3
7 2 1 9 0
4 2 2 5 0
9 2 3 7 0
6 3 4 8 10
10 1 0 0 0

Resources