How to convert an array of array to array in Julia? - arrays

In the following example I am getting an array of array as an output. I would like to seek suggestion on reducing it to n-element vector.
Example: I have a vector x and then I perform subtraction on first 2 elements of the array which outputs a.
x = Float64.([1,2,3,4,5])
a= x[2,:] - x[1,:]
1-element Vector{Float64}:
1.0
Now when i collect the following range, it returns array of array, as shown below.
c = collect(range(minimum(x).*a, maximum(x).*a, length=10))
10-element Vector{Vector{Float64}}:
[1.0]
[1.4444444444444444]
[1.8888888888888888]
[2.333333333333333]
[2.7777777777777777]
[3.2222222222222223]
[3.6666666666666665]
[4.111111111111111]
[4.555555555555555]
[5.0]
I would like to know how may I convert this to a vector, which can output following result?
# Expected result:
10-element Vector{Float64}:
1.0
1.4444444444444444
1.8888888888888888
2.333333333333333
2.7777777777777777
3.2222222222222223
3.6666666666666665
4.111111111111111
4.555555555555555
5.0
Thanks!!

When constructing a you want a= x[2] - x[1]. Then a will be a scalar, and everything else will behave as expected.

In general, you can use a combination of splatting and vcat:
julia> xs = [[1],[2,3],[],[4],[5,6,7]]
5-element Vector{Vector{Any}}:
[1]
[2, 3]
[]
[4]
[5, 6, 7]
julia> vcat(xs...)
7-element Vector{Any}:
1
2
3
4
5
6
7
That being said, I would follow Oscar Smith's advice and fix the root problem.

Related

Julia accessing specific Matrix elements using vectors as indexes

Suppose I have a 4*2 matrix as follows:
a = [1 2; 3 4; 5 6; 7 8]
4×2 Matrix{Int64}:
1 2
3 4
5 6
7 8
I want to access the matrix using a vector specifying which element I want to access in each column. In NumPy from python, I would do the following command:
a[[1,3], [1,2]]
# expected output:
1×2 Matrix{Int64}:
1(as a[1,1]) 6(as a[3,2])
but in Julia, I got the following matrix:
2×2 Matrix{Int64}:
1 2
5 6
How can I do it in an julia way?
UPDATE: Inspired by DNF answer:
julia> a[CartesianIndex.([1 3], [1 2])]
1×2 Matrix{Int64}:
1 6
seems to me the right balance of clarity and similarity to OP.
ORIGINAL answer:
Maybe not the optimal way, but:
[a[x...] for x in [[[1,1]] [[3,2]]]]
works.
Note that this returns a row vector, like in the OP. In Julia there is a difference between a vector and a matrix. A matrix with one row or one column is not the same as a vector.
The [[]] notation is to let hcat handle vector elements correctly. If a vector output is good enough, then: [[1,1],[3,2]] is enough.
The syntax a[i, j] is syntax sugar for getindex(a, i, j). You can broadcast getindex to get the desired behavior (unfortunately, you cannot broadcast the [] syntax itself):
getindex.(Ref(a), [1,3], [1,2])
You must protect a itself against being broadcasted, by wrapping it in a Ref.

Remove a value in an array and decrease the size of it

I have an array filled with some values. After running this code:
array = zeros(10)
for i in 1:10
array[i] = 2*i + 3
end
The array looks like:
10-element Array{Float64,1}:
5.0
7.0
9.0
11.0
13.0
15.0
17.0
19.0
21.0
23.0
I would like to obtain, for example, the following array by removing the third value:
9-element Array{Float64,1}:
5.0
7.0
11.0
13.0
15.0
17.0
19.0
21.0
23.0
How to do that?
EDIT
If I have an array (and not a vector), like here:
a = [1 2 3 4 5]
1×5 Array{Int64,2}:
1 2 3 4 5
The deleteat! proposed is not working:
a = deleteat!([1 2 3 4 5], 1)
ERROR: MethodError: no method matching deleteat!(::Array{Int64,2}, ::Int64)
You might have used a 2d row vector where a 1d column vector was required.
Note the difference between 1d column vector [1,2,3] and 2d row vector [1 2 3].
You can convert to a column vector with the vec() function.
Closest candidates are:
deleteat!(::Array{T,1} where T, ::Integer) at array.jl:875
deleteat!(::Array{T,1} where T, ::Any) at array.jl:913
deleteat!(::BitArray{1}, ::Integer) at bitarray.jl:961
I don't want a column vector. I would want:
1×4 Array{Int64,2}:
2 3 4 5
Is it possible ?
To make that clear: Vector{T} in Julia is just a synonym for Array{T, 1}, unless you're talking about something else... we call Arrays of all ranks arrays.
But this seems to be a Matlab-inherited misconception. In Julia, you construct a Matrix{T}, ie., an Array{T, 2}, by using spaces in the literal:
julia> a = [1 2 3 4 5]
1×5 Array{Int64,2}:
1 2 3 4 5
Deleting from a matrix does not make sense in general, since you can't trivially "fix the shape" in a rectangular layout.
A Vector or Array{T, 1} can be written using commas:
julia> a = [1, 2, 3, 4, 5]
5-element Array{Int64,1}:
1
2
3
4
5
And on this, deleteat! works:
julia> deleteat!(a, 1)
4-element Array{Int64,1}:
2
3
4
5
For completeness, there's also a third variant, the RowVector, which results of a transposition:
julia> a'
1×4 RowVector{Int64,Array{Int64,1}}:
2 3 4 5
From this you also can't delete.
Deleteat! is only defined for:
Fully implemented by:
Vector (a.k.a. 1-dimensional Array)
BitVector (a.k.a. 1-dimensional BitArray)
A Row Vector (2 Dimensions) won't work.
But ... there is a workaround by this trick:
julia> deleteat!(a[1,:], 1)' # mind the ' -> transposes it back to a row vector.
1×4 RowVector{Int64,Array{Int64,1}}:
2 3 4 5
Ofcourse this wouldn't work for an Array with 2 or more rows.

The best way to convert Vector into Matrix in Julia?

Suppose I have a variable v of a type Vector.
What would be the best / fastest way to just convert it into Matrix representation (for whatever reason)?
To clarify, v'' will do the job, but is it the best way to do this?
Reshape should be the most efficient. From the docs:
reshape(A, dims): Create an array with the same data as the given array, but with different dimensions. An implementation for a particular type of array may choose whether the data is copied or shared.
julia> v = rand(3)
3-element Array{Float64,1}:
0.690673
0.392635
0.0519467
julia> reshape(v, length(v), 1)
3x1 Array{Float64,2}:
0.690673
0.392635
0.0519467
v[:,:] is probably the clearest way to do this.
For example:
julia> v=[1,2,3]
3-element Array{Int64,1}:
1
2
3
julia> m=v[:,:]
3x1 Array{Int64,2}:
1
2
3
julia> ndims(m)
2
Or just use:
v = [1, 2, 3]
hcat(v)
Result:
3×1 Array{Int64,2}:
1
2
3

Julia Reverse N-dimensional arrays

In Python, Numpy arrays can be reversed using the standard [::-1] i.e.
A = np.diag(np.arange(1,3))
A[::, ::-1]
A[::-1]
A[::-1, ::-1]
Julia does not support [::-1] and the reverse method only works on 1D arrays and only 1D columns (where as rows are 2D by default).
Is there an alternative I'm missing?
Try the following, which is essentially the same as the numpy version:
julia> X = rand(3,3)
3x3 Array{Float64,2}:
0.782622 0.996359 0.335781
0.719058 0.188848 0.985693
0.455355 0.910717 0.870187
julia> X[end:-1:1,end:-1:1]
3x3 Array{Float64,2}:
0.870187 0.910717 0.455355
0.985693 0.188848 0.719058
0.335781 0.996359 0.782622
In Julia 1.0, to reverse a (column) vector:
julia> reverse([1, 2, 3])
3-element Array{Int64,1}:
3
2
1
For reversing rows, just state that you want to flip the second dimension:
julia> reverse([1 2 3], dims=2)
1×3 Array{Int64,2}:
3 2 1
EDIT: Alternatively, you can also index in reverse using end:-1:1, and that way also allows you to request a view instead of a copy:
julia> a = reshape(randperm(9), 3, 3)
3×3 Matrix{Int64}:
4 7 9
5 2 1
3 6 8
julia> #view a[:, end:-1:1]
3×3 view(::Matrix{Int64}, :, 3:-1:1) with eltype Int64:
9 7 4
1 2 5
8 6 3
Following up #IainDunning's answer, an important difference between numpy and Julia here is that X[:,end:-1:1] in Julia returns a copy and in numpy X[:,::-1] will return a view of the same data (no copy is made).
I'm just learning Julia myself, but it seems like you can accomplish something similar in Julia using sub(X, :, size(X)[2]:-1:1), which returns Julia's equivalent of a view (SubArray). Interestingly, you can't use the end keyword in this construct as far as I can see, and instead you must pass in the actual end index in the dimension.
You can use the function flipdim(mat, d).
Ref: http://docs.julialang.org/en/release-0.4/stdlib/arrays/
Try this set of functions:
function reverser(x::AbstractArray, dims::AbstractVector{<:Integer})
y = copy(x)
for d in dims
y = reverse(y, dims=d)
end
return y
end
reverser(x::AbstractArray) = reverser(x, 1:ndims(x)) # all dimensions
reverser(x::AbstractArray, d::Integer) = reverser(x, [1])
Julia 1.6 supports reversing any or all of the dimensions of an arbitrary multidimensional array (implemented here). To reverse all of the dimensions, you can simply do reverse(X).

Array Multiplication in Julia

I'm trying to do something that I believe should be relatively simple in Julia, but I can't seem to find any mention of this problem.
Basically what I've got is an mxn matrix, and an nx1 vector. What I would like to do is multiply the vector against the matrix, elementwise, but along the axis such that every element of the matrix is multiplied.
In numpy for instance this would be:
np.multiply(array, vector)
Is there any way to do this in Julia?
I tried just extending the vector to fill an array:
projection = 1:size(matrix)[1]
weight_change = hcat(map(x -> vector, projection))
but that yields something with a type of Array{Array{Float64, 2}, 2}, when what I really need is just Array{Float64, 2}, which means that an elementwise multiplication won't really work.
Is there any way to either fix my approach or remedy my bugged solution?
You're looking for the .* element-wise, broadcasting multiply operator:
julia> A = [ i + j*im for i=1:3, j=1:4 ]
3x4 Array{Complex{Int64},2}:
1+1im 1+2im 1+3im 1+4im
2+1im 2+2im 2+3im 2+4im
3+1im 3+2im 3+3im 3+4im
julia> v = [1:4]
4-element Array{Int64,1}:
1
2
3
4
julia> w = [1:3]
3-element Array{Int64,1}:
1
2
3
julia> A .* w
3x4 Array{Complex{Int64},2}:
1+1im 1+2im 1+3im 1+4im
4+2im 4+4im 4+6im 4+8im
9+3im 9+6im 9+9im 9+12im
julia> A .* v'
3x4 Array{Complex{Int64},2}:
1+1im 2+4im 3+9im 4+16im
2+1im 4+4im 6+9im 8+16im
3+1im 6+4im 9+9im 12+16im

Resources