Array indexing with multiple conditions

I have a two-dimensional array and I want to select based on the values in certain columns. For example, let’s think of data to be an 1000x14 Array{Float64,2}. I can do

data[data[:,3].>-9.0,:]

but when I do

data[data[:,3].>-9.0 & data[:,3].<25.0,:]

I get an error that says

**ERROR:** MethodError: no method matching &(::Float64, ::Array{Float64,1})
Closest candidates are:
&(::Any, ::Any, ::Any, ::Any...) at operators.jl:538
Stacktrace:
[1] top-level scope at **REPL[96]:1**

Any suggestions on how I can manage to do this without making use of DataFrames?

Thanks!

1 Like

There are two things here:

  • You need to .& just like the other operators to make it work element-wise, too
  • You need to use parentheses because &'s precedence is different from &&.
data[(data[:,3] .> -9.0) .& (data[:,3] .< 25.0),:]

Alternatively, you could combine them into a single chained comparison in this particular case:

data[-9.0 .< data[:,3] .< 25.0,:]
8 Likes

This is great. Thanks so much for the help!

And since this can a bit visually dense, you can drop some characters without sacrificing performance or clarity:

data[-9 .< data[:,3] .< 25, :]

You don’t need the comparison values to be actual floats.

For performance reasons you could also consider using views.

For what it’s worth, I’d expect views to slightly speed up the data[:,3] operation and the generation of the logical index but be slower for the final logical indexing expression. YMMV depending upon array types and sizes and downstream uses.

1 Like