# Boolean indexing with multidimensional array

**URL:** <https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452>\
**Category:** New to Julia\
**Created:** [October 17, 2018, 5:21pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452 "2018-10-17T17:21:12Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![lnacquaroli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lnacquaroli/32/20467_2.png) [@lnacquaroli](https://discourse.julialang.org/u/lnacquaroli)\
**Post date:** [October 17, 2018, 5:21pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452/1 "2018-10-17T17:21:12Z")

</div>

I have been trying to filter a 2d-array with boolean indexing without much success. For instance,

```julia
B = randn(5,5)
s = B .> 0
B[s] # this produces a 1d array with those values that give s == true

```

However, since I want is to plot with `contourf` those values in `B[s]` keeping those that does not satisfy the the `s` condition as well. The problem is that I get the 1d-array satisfying the `s` conditions instead of the whole 2d-array and the plot does not work with this. What I tried to do to obtain the desired result is

```julia
B.*s

```

which gives the filtered matrix with the same original size of `B`. But not sure if this is an effective way of doing things, especially when lengths of arrays goes up to, say 10^4.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 17, 2018, 5:35pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452/2 "2018-10-17T17:35:31Z")

</div>

It’s a bit hard to understand what you want the end result to be for the cases where the element is `< 0`.

Perhaps you are looking for

```julia
julia> clamp.(B, 0, Inf)
5×5 Array{Float64,2}:
 0.0 1.63247 0.0 0.0 0.0     
 1.23743 0.0191958 0.417646 0.0 1.17548 
 0.0 0.0 0.42163 0.601486 0.726729
 0.0 0.0 0.0 0.0 0.360118
 0.420498 0.0 0.0 2.44904 0.0 

```

---

<div class="post-metadata">

**Author:** ![lnacquaroli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lnacquaroli/32/20467_2.png) [@lnacquaroli](https://discourse.julialang.org/u/lnacquaroli)\
**Post date:** [October 17, 2018, 6:06pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452/3 "2018-10-17T18:06:52Z")

</div>

I was trying to plot with `contourf` a complex variable showing only those values that have zero imaginary part, discarding the others, but keeping the same size of the original array. The working example wasn’t probably appropriate enough (noted). Here it goes again:

```julia
julia> B
3×3 Array{Complex{Float64},2}:
  0.542545+0.0im 0.925355-0.487208im 1.65225+0.806615im
 -0.927869+0.847093im -0.309946+1.53378im 0.444565+0.0im     
 -0.048035+0.260424im 0.937434+0.0im -0.153685-1.71329im

```

Now, if I do `s = imag.(B) .== 0`, then

```julia
B[s]
3-element Array{Complex{Float64},1}:
  0.5425454 + 0.0im
   0.937434 + 0.0im
 0.44456454 + 0.0im

```

But is hard to plot this way. What I really want is the original matrix `B` with those values that have zero imaginary part sent to zero. For instance,

```julia
julia> B.*s
3×3 Array{Complex{Float64},2}:
 0.542545+0.0im 0.0-0.0im 0.0+0.0im
     -0.0+0.0im -0.0+0.0im 0.444565+0.0im
     -0.0+0.0im 0.937434+0.0im -0.0-0.0im

```

Hope is illustrative enough.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [October 17, 2018, 6:15pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452/4 "2018-10-17T18:15:04Z")

</div>

Indexing is, at its core, simply a _selection_ API. It chooses which locations you want to have returned. Or modified, in the case of `setindex!`. As such, you can use boolean indexing to _change_ the values as you’d like:

```julia
B[imag.(B) .== 0] .= 0

```

Broadcasted `clamp` is another great tool as @kristoffer.carlsson mentions, as is broadcasted `ifelse`:

```julia
ifelse.(imag.(B) .== 0, missing, B)

```

---

<div class="post-metadata">

**Author:** ![stillyslalom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stillyslalom/32/45687_2.png) [@stillyslalom](https://discourse.julialang.org/u/stillyslalom)\
**Post date:** [October 17, 2018, 6:16pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452/5 "2018-10-17T18:16:30Z")

</div>

If you’re worried about runtime, the best way to avoid it is to plot fewer points. The plotting library runtime will be orders of magnitude larger than the difference in runtime between indexing methods. Your screen only has so many pixels–you won’t lose much by downsampling your array to the desired plotting resolution.

```julia
using Plots, BenchmarkTools

function full_contour!(A)
    A[imag(A) .< 0] .= 0
    contourf(abs.(A))
end

function resampled_contour(A, res)
    B = A[1:(size(A,1)÷res):end, 1:(size(A,2)÷res):end]
    B[imag(B) .< 0] .= 0
    contourf(abs.(B))
end

@btime full_contour!(A) setup=(A = randn(ComplexF64, 5000, 5000));
@btime resampled_contour($A, 500) setup=(A = randn(ComplexF64, 5000, 5000));

```

```julia
1.180 s (2848 allocations: 670.74 MiB) # full_contour!
12.141 ms (2850 allocations: 10.72 MiB) # resampled_contour

```

---

<div class="post-metadata">

**Author:** ![lnacquaroli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lnacquaroli/32/20467_2.png) [@lnacquaroli](https://discourse.julialang.org/u/lnacquaroli)\
**Post date:** [October 17, 2018, 6:20pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452/6 "2018-10-17T18:20:07Z")

</div>

Yeah, both worked. Thank you guys.

---

<div class="post-metadata">

**Author:** ![bennedich](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bennedich/32/4894_2.png) [@bennedich](https://discourse.julialang.org/u/bennedich)\
**Post date:** [October 17, 2018, 8:21pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452/7 "2018-10-17T20:21:41Z")

</div>

Don’t forget comprehension! (Which creates a new matrix.) Also note that you can use `isreal` to check for zero imaginary part.

```julia
C = [isreal(x) ? 0.0im : x for x in B]

```

---

<div class="post-metadata">

**Author:** ![lnacquaroli](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lnacquaroli/32/20467_2.png) [@lnacquaroli](https://discourse.julialang.org/u/lnacquaroli)\
**Post date:** [October 18, 2018, 12:58pm UTC](https://discourse.julialang.org/t/boolean-indexing-with-multidimensional-array/16452/8 "2018-10-18T12:58:55Z")

</div>

I took for granted that if the variable is actually complex, `isreal` would be false independently of the values. Good to know. Thanks.
