`filter` with `eachrow`

Suppose I have an array with two columns. I want to filter the array based on the values of the first column, but would like what is returned by filter to include the second column. This method seems to be missing from filter.

Example:

A = rand(100,2)
filter( x-> x[1]>0.5, eachrow(A))
ERROR: MethodError: no method matching filter(::var"#78#79", ::Base.Generator{Base.OneTo{Int64}, Base.var"#191#192"{Matrix{Float64}}})

I can do

map( x->x[1] > 0.5, eachrow(A))

But to do

A[ map( x->x[1] > 0.5, eachrow(A)), :]

seems cumbersome. Is there something I’m missing about filter or eachrow that would make the option directly using filter work? Or was this method excluded for a reason I’m not seeing?

I believe this is possible with Iteration utilities · The Julia Language

using Base.Iterators
Iterators.filter( x-> x[1]>0.5, eachrow(A)) |> collect

or

Iterators.filter( x-> x[1]>0.5, eachrow(A)) |>
    xs -> mapreduce(transpose, vcat, xs)
1 Like

The following seems to get the job done too:

filter.(x-> x[1]>0.5, Ref(collect(eachrow(A))))

There are other options, but this seems short and is twice as fast:

A[view(A,:,1).>0.5, :]
1 Like

Great answers. Thanks. The first one seems closest to what I needed.

Just use splitdims instead of eachrow: it returns a vector and supports filter.

using SplitApplyCombine

filter(x->x[1]>0.5, splitdims(A, 1))

or splitdimsview to get views instead of copies.

1 Like