# Picking elements of an array

Hi,

Suppose I have an array `a` like the following

``````5Γ2 Matrix{Float64}:
2.0  1.0
3.0  0.0
4.0  1.0
2.0  0.0
4.0  1.0
``````

The second column can only be 0 or 1. Now I want to pick the rows whose second element is 0 and store the first elements of these rows into a new array. In the example, I should have

``````b =[3.0,4.0]
``````

How to achieve this goal?

Also, since my second column can only have 0 or 1. So in principle I can use Boolean variables. How to initiate my array such that the first column is 0(float64) and the second column is false (Bool).

Thanks

``````julia> a = [ 2.0  1.0
3.0  0.0
4.0  1.0
2.0  0.0
4.0  1.0]

julia> indices = findall(iszero,a[:,2])
2-element Vector{Int64}:
2
4

julia> b = a[indices,1]
2-element Vector{Float64}:
3.0
2.0

``````

To have a table with different types for each column, you can use DataFrames from the DataFrames package:

``````julia>  using DataFrames
# you might need to install package if it isn't yet

julia> df = DataFrame(a1=[2.0, 3.0, 4.0, 2.0, 4.0],
a2= [true, false, true, false, true])
5Γ2 DataFrame
Row β a1       a2
β Float64  Bool
ββββββΌββββββββββββββββ
1 β     2.0   true
2 β     3.0  false
3 β     4.0   true
4 β     2.0  false
5 β     4.0   true

julia> df.a1[(!).(df.a2)]
2-element Vector{Float64}:
3.0
2.0
``````

The last line calculates the result (it uses `!` and broadcasting `.` which require paranthesis because of parsing issues).

1 Like

Array comprehensions are pretty good for this purpose.

``````julia> M = Float64[2 1; 3 0; 4 1; 2 0; 4 1]
5Γ2 Matrix{Float64}:
2.0  1.0
3.0  0.0
4.0  1.0
2.0  0.0
4.0  1.0

julia> [first(r) for r in eachrow(M) if last(r) == 1]
3-element Vector{Float64}:
2.0
4.0
4.0

julia> [first(r) for r in eachrow(M) if last(r) == 0]
2-element Vector{Float64}:
3.0
2.0
``````

The simplest and most direct way is to use a vector of tuples: `A = [(2.0, true), (3.0, false), ...)]`.
If you need convenient access to components of the array, `StructArrays` are a great fit. They have the same array interface, with extra functionality:

``````julia> A = [(2.0, true), (3.0, false), (4.0, true)] |> StructArray

julia> A.:1  # == [2.0, 3.0, 4.0]

julia> A.:2  # == [true, false, true]

julia> A[1]  # == (2.0, true)

julia> b = A.:1[.!A.:2]
# or
julia> filter(x -> !x[2], A).:1
``````

Everything here is efficient, and continues to works with all array/collection functions.

1 Like

Slightly off topic: Iβve seen this `(!).` idiom a lot, but `.!` works perfectly fine (with the dot in front, as with any operator):

``````julia> x = [false, true, false]
3-element Vector{Bool}:
0
1
0

julia> .!x
3-element BitVector:
1
0
1
``````
1 Like

A tuple of arrays is also simple and direct:

``````A = (Float64[2, 3, 4, 2, 4], Bool[1, 0, 1, 0, 1])
([2.0, 3.0, 4.0, 2.0, 4.0], Bool[1, 0, 1, 0, 1])

julia> A[1][A[2]]
3-element Vector{Float64}:
2.0
4.0
4.0

julia> A[1][.!A[2]]
2-element Vector{Float64}:
3.0
2.0
``````

In fact you could also use a `NamedTuple`:

``````julia> NT = (floats = Float64[2, 3, 4, 2, 4], bools = Bool[1, 0, 1, 0, 1])
(floats = [2.0, 3.0, 4.0, 2.0, 4.0], bools = Bool[1, 0, 1, 0, 1])

julia> NT.floats[NT.bools]
3-element Vector{Float64}:
2.0
4.0
4.0

julia> NT.floats[.!NT.bools]
2-element Vector{Float64}:
3.0
2.0
``````
2 Likes

I donβt think the example in the original post has the correct result β if I (and several other posters) understand correctly, the result should be `b=[3.0,2.0]`.

Other peopleβs notes about arrays of tuples or struct arrays are probably the better solutions. But to answer the original question directly, this looks like a good candidate for logical indexing:

``````julia> a = [2.0 1.0; 3.0 0.0; 4.0 1.0; 2.0 0.0; 4.0 1.0]
5Γ2 Matrix{Float64}:
2.0  1.0
3.0  0.0
4.0  1.0
2.0  0.0
4.0  1.0

julia> b = a[@view(a[:, 2]) .== 0, 1] # the @view() is unnecessary but gives slightly better performance
2-element Vector{Float64}:
3.0
2.0
``````

Some of the other suggested methods (the comprehensions in particular) might be marginally more efficient than this, however.