I have an array a = [1, 2, 3, 4];. I want to compare each element of array a with a number and return a new array contains True/False elements in Julia as few steps as possible. I try result = a < 2 and expected array is result = [True, False, False, False] but it's not working. Hope your help
You need to vectorize (broadcast) the comparison operator so it operates on Vectors.
You can do this by adding a dot . to your code.
julia> a = [1, 2, 3, 4]
4-element Vector{Int64}:
1
2
3
4
julia> a .<= 2
4-element BitVector:
1
1
0
0
Read more about broadcasting here.
Note that Python's numpy will do this for you automatically, but there are cases where an operation might be ambiguous - do you want it to be element wise or a matrix multiplication? So Julia solves this by explicitly broadcasting any operation with the . command.
Is there a method in julia to convert a multidimensional array to a vector of vector and so on, and vice versa? It is OK to define a method for a fix number of dimensions. But how about a method for arbitrary dims?
julia> s = (1,2,3)
julia> a = reshape(1:prod(s), s)
1×2×3 Base.ReshapedArray{Int64,3,UnitRange{Int64},Tuple{}}:
[:, :, 1] =
1 2
[:, :, 2] =
3 4
[:, :, 3] =
5 6
julia> b = [[[a[i,j,k] for i=1:s[1]] for j=1:s[2]] for k=1:s[3]]
3-element Array{Array{Array{Int64,1},1},1}:
Array{Int64,1}[[1], [2]]
Array{Int64,1}[[3], [4]]
Array{Int64,1}[[5], [6]]
julia> unstack(a) == b
ERROR: UndefVarError: unstack not defined
RecursiveArrayTools.jl can help with this kind of work.
recs = [rand(8) for i in 1:10]
A = VectorOfArray(recs)
A[i] # Returns the ith array in the vector of arrays
A[j,i] # Returns the jth component in the ith array
A[j1,...,jN,i] # Returns the (j1,...,jN) component of the ith array
So it acts like the matrix without ever building the matrix, which is a good way to save allocations if you tend to act on the columns (which are the separate arrays). It also has a fast conversion to a contiguous array via the indexing fallback (honestly, I tried to create a faster one but the fallback worked better than I could make it):
arr = convert(Array,A)
Converting back would require allocating of course
VA = VectorOfArray([A[:,i] for i in size(A,2)])
I have a multidimensional array 69 x 4 in JULIA. I would like to filter the rows using a condition on one of the columns of the frame.
updown[updown[:,4] .> .5]
does not seem to work.
You could pass something for the second axis, basically saying "all columns":
julia> updown = randn(69, 4);
julia> updown[updown[:, 4] .> 1.5, :]
4×4 Array{Float64,2}:
1.76637 -0.307257 -0.125816 1.89179
0.0858598 -0.812886 -0.030113 1.66113
-0.144546 0.374371 -0.731996 1.56694
0.330211 0.108665 0.98783 1.71425
First time looking at Julia
julia> x=[1 2 3];
julia> x[2]=3+5im
ERROR: InexactError()
in convert at complex.jl:18
in setindex! at array.jl:346
I am sure this is because julia typing system is different.
How would one do this below in Julia?
x=[1 2 3];
x(2)=3+5*1i
x =
1.0000 + 0.0000i 3.0000 + 5.0000i 3.0000 + 0.0000i
You can make x a complex array:
x=[1 2 3];
x=complex(x);
Now you can perform this operation:
x[2]=3+5im;
This results in x containing:
println(x)
This outputs:
1+0im 3+5im 3+0im
As desired.
You probably want x to be complex. In which case, you can do this:
x = Complex{Float64}[1, 2, 3]
Which allows you to do what you want. You can also change Float64 to something else like Int or Int64.
Also, you should put commas after entries to get 1-dimensional arrays instead of 2-dimensional arrays, which is what yours are. To find the type do this
typeof(x)
which gives
1x3 Array{Complex{Float64},1}:
1.0+0.0im 2.0+0.0im 3.0+0.0im
The 1 at the end indicates that this is a 1-dimensional array.
In python I can do nested list comprehensions, for instance I can flatten the following array thus:
a = [[1,2,3],[4,5,6]]
[i for arr in a for i in arr]
to get [1,2,3,4,5,6]
If I try this syntax in Julia I get:
julia> a
([1,2,3],[4,5,6],[7,8,9])
julia> [i for arr in a for i in arr]
ERROR: syntax: expected ]
Are nested list comprehensions in Julia possible?
This feature has been added in julia v0.5:
julia> a = ([1,2,3],[4,5,6],[7,8,9])
([1,2,3],[4,5,6],[7,8,9])
julia> [i for arr in a for i in arr]
9-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
List comprehensions work a bit differently in Julia:
> [(x,y) for x=1:2, y=3:4]
2x2 Array{(Int64,Int64),2}:
(1,3) (1,4)
(2,3) (2,4)
If a=[[1 2],[3 4],[5 6]] was a multidimensional array, vec would flatten it:
> vec(a)
6-element Array{Int64,1}:
1
2
3
4
5
6
Since a contains tuples, this is a bit more complicated in Julia. This works, but likely isn't the best way to handle it:
function flatten(x, y)
state = start(x)
if state==false
push!(y, x)
else
while !done(x, state)
(item, state) = next(x, state)
flatten(item, y)
end
end
y
end
flatten(x)=flatten(x,Array(Any, 0))
Then, we can run:
> flatten([(1,2),(3,4)])
4-element Array{Any,1}:
1
2
3
4
You can get some mileage out of using the splat operator with the array constructor here (transposing to save space)
julia> a = ([1,2,3],[4,5,6],[7,8,9])
([1,2,3],[4,5,6],[7,8,9])
julia> [a...]'
1x9 Array{Int64,2}:
1 2 3 4 5 6 7 8 9
Any reason why you're using a tuple of vectors? It's much simpler with arrays, as Ben has already shown with vec. But you can also use comprehensions pretty simply in either case:
julia> a = ([1,2,3],[4,5,6],[7,8,9]);
julia> [i for i in hcat(a...)]
9-element Array{Any,1}:
1
2
⋮
The expression hcat(a...) "splats" your tuple and concatenates it into an array. But remember that, unlike Python, Julia uses column-major array semantics. You have three column vectors in your tuple; is that what you intend? (If they were row vectors — delimited by spaces — you could just use [a...] to do the concatenation). Arrays are iterated through all elements, regardless of their dimensionality.
Don't have enough reputation for comment so posting a modification #ben-hammer. Thanks for the example of flatten(), it was helpful to me.
But it did break if the tuples/arrays contained strings. Since strings are iterables the function would further break them down to characters. I had to insert condition to check for ASCIIString to fix that. The code is below
function flatten(x, y)
state = start(x)
if state==false
push!(y, x)
else
if typeof(x) <: String
push!(y, x)
else
while (!done(x, state))
(item, state) = next(x, state)
flatten(item, y)
end
end
end
y
end
flatten(x)=flatten(x,Array(Any, 0))