The following code
a=1:1:10
collect(a)
a[a.>4]
returns the expected
6-element Array{Int64,1}:
5
6
7
8
9
10
Whereas,
a[(a.>4) & (a.<8)]
returns
MethodError: no method matching &(::Int64, ::StepRange{Int64,Int64})
How can this be resolved?
As a.>4 and a.<8 return BitArrays, you need to broadcast & with a dot (.) as well.
julia> a[(a.>4) .& (a.<8)]
3-element Array{Int64,1}:
5
6
7
Here are two alternative ways of doing it:
julia> a = 1:10
julia> a[4 .< a .< 8]
3-element Array{Int64,1}:
5
6
7
julia> filter(x->4<x<8, a)
3-element Array{Int64,1}:
5
6
7
Oh, and don't use collect.
Related
That's it. My program generates a vector of Int64s, and each time I need to stack each Vector into a M by N Matrix
Everything. e.g.
Push, Append, hcat [], (), {}, even ¯_(ツ)_/¯
If this is a new matrix use hcat:
julia> hcat([1,2,3],[4,5,6])
3×2 Matrix{Int64}:
1 4
2 5
3 6
This will also work with vector of vectors:
julia> vecs = [[1,2,3],[4,5,6],[7,8,9]];
julia> a = hcat(vecs...)
3×3 Matrix{Int64}:
1 4 7
2 5 8
3 6 9
If performance is an issue reduce combined with hcat will be more verbose but much faster:
reduce(hcat, vecs)
To put data into a column use broadcasted assignment:
julia> a[:,2] .= [40,50,60];
julia> a
3×3 Matrix{Int64}:
1 40 7
2 50 8
3 60 9
With arrays, you can filter based on a condition:
[i for i=1:10 if isodd(i) ]
returns:
5-element Vector{Int64}:
1
3
5
7
9
but attempting something similar with map results in nothing values:
julia> map(1:10) do i
isodd(i) ? i : nothing
end
reutrns:
10-element Vector{Union{Nothing, Int64}}:
1
nothing
3
nothing
5
nothing
7
nothing
9
nothing
map is a one-to-one mapping. So I'm afraid you can't do the same with map. Maybe what you are looking for is just filter?
julia> a = 1:10
1:10
julia> filter(isodd, a)
5-element Vector{Int64}:
1
3
5
7
9
Let's say I have a two-dimensional array
a = [1 2 3; 1 2 3]
2×3 Array{Int64,2}:
1 2 3
1 2 3
and I would like sum along a dimension, e.g. along dimension 1 yielding
[2, 4, 6]
or along dimension 2 yielding
[6, 6]
How is this done properly in Julia?
julia> sum(a; dims=1)
1×3 Array{Int64,2}:
2 4 6
julia> sum(a; dims=2)
2×1 Array{Int64,2}:
6
6
You can drop the dimension with vec.
What Jun Tian suggests is the standard way to do it. However, it is also worth to know a more general pattern:
julia> sum.(eachrow(a))
2-element Array{Int64,1}:
6
6
julia> sum.(eachcol(a))
3-element Array{Int64,1}:
2
4
6
In this case sum can be replaced by any collection aggregation function.
Note: This question/answer is copied from the Julia Slack channel.
If I have an arbitrary Julia Array, how can I add another dimension.
julia> a = [1, 2, 3, 4]
4-element Array{Int64,1}:
1
2
3
4
The desired output would be e.g.:
julia> a[some_magic, :]
1×4 Array{Int64,2}:
1 2 3 4
Or:
julia> a[:, some_magic]
4×1 Array{Int64,2}:
1
2
3
4
A less tricky thing I usually do to achieve this is:
julia> reshape(a, 1, :)
1×4 Array{Int64,2}:
1 2 3 4
julia> reshape(a, :, 1)
4×1 Array{Int64,2}:
1
2
3
4
(it also seems to involve less typing)
Finally a common case requiring transforming a vector to a column matrix can be done:
julia> hcat(a)
4×1 Array{Int64,2}:
1
2
3
4
EDIT also if you add trailing dimensions you can simply use ::
julia> a = [1,2,3,4]
4-element Array{Int64,1}:
1
2
3
4
julia> a[:,:]
4×1 Array{Int64,2}:
1
2
3
4
julia> a[:,:,:]
4×1×1 Array{Int64,3}:
[:, :, 1] =
1
2
3
4
The trick is so use [CartesianIndex()] to create the additional axes:
julia> a[[CartesianIndex()], :]
1×4 Array{Int64,2}:
1 2 3 4
And:
julia> a[:, [CartesianIndex()]]
4×1 Array{Int64,2}:
1
2
3
4
If you want to get closer to numpy's syntax, you can define:
const newaxis = [CartesianIndex()]
And just use newaxis.
If the two Int arrays are, a = [1;2;3] and b = [4;5;6], how do we concatenate the two arrays in both the dimensions? The expected outputs are,
julia> out1
6-element Array{Int64,1}:
1
2
3
4
5
6
julia> out2
3x2 Array{Int64,2}:
1 4
2 5
3 6
Use the vcat and hcat functions:
julia> a, b = [1;2;3], [4;5;6]
([1,2,3],[4,5,6])
help?> vcat
Base.vcat(A...)
Concatenate along dimension 1
julia> vcat(a, b)
6-element Array{Int64,1}:
1
2
3
4
5
6
help?> hcat
Base.hcat(A...)
Concatenate along dimension 2
julia> hcat(a, b)
3x2 Array{Int64,2}:
1 4
2 5
3 6
Square brackets can be used for concatenation:
julia> a, b = [1;2;3], [4;5;6]
([1,2,3],[4,5,6])
julia> [a; b]
6-element Array{Int64,1}:
1
2
3
4
5
6
julia> [a b]
3×2 Array{Int64,2}:
1 4
2 5
3 6
You can use the cat function to concatenate any number of arrays along any dimension. The first input is the dimension over which to perform the concatenation; the remaining inputs are all of the arrays you wish to concatenate together
a = [1;2;3]
b = [4;5;6]
## Concatenate 2 arrays along the first dimension
cat(1,a,b)
6-element Array{Int64,1}:
1
2
3
4
5
6
## Concatenate 2 arrays along the second dimension
cat(2,a,b)
3x2 Array{Int64,2}:
1 4
2 5
3 6
## Concatenate 2 arrays along the third dimension
cat(3,a,b)
3x1x2 Array{Int64,3}:
[:, :, 1] =
1
2
3
[:, :, 2] =
4
5
6
when encountered Array{Array,1}, the grammer is a little bit different, like this:
julia> a=[[1,2],[3,4]]
2-element Array{Array{Int64,1},1}:
[1, 2]
[3, 4]
julia> vcat(a)
2-element Array{Array{Int64,1},1}:
[1, 2]
[3, 4]
julia> hcat(a)
2×1 Array{Array{Int64,1},2}:
[1, 2]
[3, 4]
julia> vcat(a...)
4-element Array{Int64,1}:
1
2
3
4
julia> hcat(a...)
2×2 Array{Int64,2}:
1 3
2 4
ref:
... combines many arguments into one argument in function definitions
In the context of function definitions, the ... operator is used to combine many different arguments into a single argument. This use of ... for combining many different arguments into a single argument is called slurping
Functional way to concatanate 2 arrays is to use reduce function.
a = rand(10, 1)
b = rand(10, 1)
c = reduce(hcat, [ a, b])