# How to obtain indices of an array satisfying boolean condition

**URL:** <https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780>\
**Category:** New to Julia\
**Created:** [April 17, 2020, 7:41pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780 "2020-04-17T19:41:07Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 17, 2020, 7:41pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/1 "2020-04-17T19:41:07Z")

</div>

I am trying to find the optimum way of obtaining the indices of an array which satisfy a certain boolean condition. For example, if `a` is of type `Array{Float64,1}`, i wish to obtain an array of indices i for which `a[i]>0`. This task can be easily accomplished by using a loop, but that would not be optimal.

I have looked extensively in the documentation for the [Base class](https://docs.julialang.org/en/v1/base/collections/#Iterable-Collections-1), but didnt find something that achieves what I am aiming for. There are some nice functions such as `filter(f, a::AbstractArray)` which does not return the indices but the elements at the indices.

---

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [April 17, 2020, 7:42pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/2 "2020-04-17T19:42:56Z")

</div>

`a[a .> 0]` ?

---

<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:** [April 17, 2020, 8:00pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/3 "2020-04-17T20:00:25Z")

</div>

```julia
julia> A = randn(10)
10-element Array{Float64,1}:
 -0.10597385263640592
  0.6804124752504479 
 -0.745552871357189  
 -0.8316766727532244 
 -0.4136441092819935 
 -1.7795858830337792 
 -0.7049887890183149 
  1.495347684116737  
 -0.05797357451997173
  0.1689282220877404 

julia> findall(>(0), A)
3-element Array{Int64,1}:
  2
  8
 10

```

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [April 17, 2020, 8:13pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/4 "2020-04-17T20:13:06Z")

</div>

A loop would (presumably) be optimal for the computer, but I agree that less typing should be required, and hence it’s not necessarily optimal for the human.

Although you probably would have spent less time writing the loop than looking in the docs and writing this post!

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 17, 2020, 8:55pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/5 "2020-04-17T20:55:49Z")

</div>

I have read that Julia’s inline commands such as `findall` are highly optimized and always recommended over explicit loops.

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 17, 2020, 8:57pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/6 "2020-04-17T20:57:27Z")

</div>

This still does not give the indices. But it was useful knowing about this notation. Thank you.

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 17, 2020, 9:04pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/7 "2020-04-17T21:04:28Z")

</div>

Thank you for suggesting `findall`. It worked very well. However, I think there is a slight mistake in your notation, since I get

```julia
 findall(>(0), a)
ERROR: MethodError: no method matching >(::Int64)
Closest candidates are:
  >(::Any, ::Any) at operators.jl:286
  >(::BigFloat, ::BigFloat) at mpfr.jl:756
Stacktrace:
 [1] top-level scope at none:0

```

However, the following syntax works.

```julia
 findall(i->(i>0.5), a)
``
```

---

<div class="post-metadata">

**Author:** ![dpo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpo/32/3335_2.png) [@dpo](https://discourse.julialang.org/u/dpo)\
**Post date:** [April 17, 2020, 9:20pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/8 "2020-04-17T21:20:26Z")

</div>

I misread your question, sorry.

---

<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:** [April 17, 2020, 9:22pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/9 "2020-04-17T21:22:51Z")

</div>

Single-argument comparisons were added in v1.2, so you must be using an older release. See [https://github.com/JuliaLang/julia/blob/master/HISTORY.md#new-library-functions-2](https://github.com/JuliaLang/julia/blob/master/HISTORY.md#new-library-functions-2)

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 17, 2020, 10:51pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/10 "2020-04-17T22:51:57Z")

</div>

I see ! Thanks

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 18, 2020, 8:34am UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/11 "2020-04-18T08:34:26Z")

</div>

> [@iamsuddhasattwa](#):
>
> I have read that Julia’s inline commands such as `findall` are highly optimized and always recommended over explicit loops.

I am curious where you read this. Loops are very efficient in Julia when written right (eg using `eachindex` etc).

---

<div class="post-metadata">

**Author:** ![dpsanders](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dpsanders/32/3573_2.png) [@dpsanders](https://discourse.julialang.org/u/dpsanders)\
**Post date:** [April 18, 2020, 8:47am UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/12 "2020-04-18T08:47:39Z")

</div>

```julia
julia> v = randn(1000);

julia> function myfindall(condition, x)
       results = Int[]

       for i in 1:length(x)
           if condition(x[i])
               push!(results, i)
           end
       end
       return results
       end
myfindall (generic function with 1 method)

julia> @btime findall(x -> x > 0, $v);
  3.438 μs (13 allocations: 8.47 KiB)

julia> @btime myfindall(x -> x > 0, $v);
  3.707 μs (9 allocations: 8.33 KiB)

```

---

<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:** [April 18, 2020, 9:02am UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/13 "2020-04-18T09:02:46Z")

</div>

> [@Tamas\_Papp](#):
>
> I am curious where you read this. Loops are very efficient in Julia when written right (eg using `eachindex` etc).

While true, the Base implementations might use tricks and optimizations that are not always obvious which often make them faster than the naive for loop.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 18, 2020, 9:15am UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/14 "2020-04-18T09:15:34Z")

</div>

But the Base implementations aren’t ‘privileged’. With some experience anyone could implement their own version that matches Base, or does even better if they have special knowledge of the specific problem.

So, @iamsuddhasattwa, you shouldn’t dismiss the possibility of writing your own implementation, though `findall` may be what you were looking for this time.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [April 18, 2020, 9:46am UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/15 "2020-04-18T09:46:22Z")

</div>

Here’s an example of how you can beat the Base implementation of `findall` for a special case. Let’s say, for example, that you know that most of the elements in your array satisfy your condition. Then it can be more efficient to allocate a large output array in the first place rather than growing it dynamically, like `findall` does:

```julia
function myfindall(p, X)
    out = Vector{Int}(undef, length(X))
    ind = 0
    @inbounds for (i, x) in pairs(X)
        if p(x)
            out[ind+=1] = i
        end
    end
    resize!(out, ind)
    return out
end

```

There’s nothing magical going on, just ordinary code you can write yourself. Now let’s benchmark:

```julia
julia> @benchmark findall(>(0.1), r) setup=(r=rand(1000))
BenchmarkTools.Trial: 
  memory estimate: 16.55 KiB
  allocs estimate: 14
  --------------
  minimum time: 8.982 μs (0.00% GC)
  median time: 10.557 μs (0.00% GC)
  mean time: 13.389 μs (17.23% GC)
  maximum time: 8.171 ms (99.39% GC)
  --------------
  samples: 10000
  evals/sample: 1

julia> @benchmark myfindall(>(0.1), r) setup=(r=rand(1000))
BenchmarkTools.Trial: 
  memory estimate: 7.94 KiB
  allocs estimate: 1
  --------------
  minimum time: 746.443 ns (0.00% GC)
  median time: 1.241 μs (0.00% GC)
  mean time: 2.408 μs (48.33% GC)
  maximum time: 73.695 μs (98.12% GC)
  --------------
  samples: 10000
  evals/sample: 122

```

So, my homemade solution beats the builtin `findall` by a factor of 10 in this special case. ( **Edit:** I moved the `@inbounds` for an even bigger speedup.)

For the record, here is the Base implementation of `findall`:

```julia
findall(testf::Function, A) = collect(first(p) for p in pairs(A) if testf(last(p)))

```

See how simple it is, almost trivial. It’s actually amazing.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [April 18, 2020, 12:36pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/16 "2020-04-18T12:36:45Z")

</div>

> [@kristoffer.carlsson](#):
>
> Base implementations might use tricks and optimizations that are not always obvious which often make them faster than the naive for loop

I am not sure what you consider a “naive” loop, but most loops which just traverse something in a memory-friendly order are usually on par with what `Base` does when the [performance tips](https://docs.julialang.org/en/v1/manual/performance-tips) are kept in mind. For the rest, yes, some tricks can be necessary. The majority of the constructs that make `Base` implementations fast are exposed.

I would say that loops are usually one of the fastest solution in Julia, and the only reason _not_ to apply them is code clarity: more abstract code is usually easier to understand.

---

<div class="post-metadata">

**Author:** ![iamsuddhasattwa](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/iamsuddhasattwa/32/7441_2.png) [@iamsuddhasattwa](https://discourse.julialang.org/u/iamsuddhasattwa)\
**Post date:** [April 18, 2020, 2:04pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/17 "2020-04-18T14:04:21Z")

</div>

Thanks! That was very eye opening.

---

<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:** [April 18, 2020, 2:18pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/18 "2020-04-18T14:18:41Z")

</div>

> [@Tamas\_Papp](#):
>
> I am not sure what you consider a “naive” loop, but most loops which just traverse something in a memory-friendly order are usually on par with what `Base` does when the [performance tips](https://docs.julialang.org/en/v1/manual/performance-tips) are kept in mind.

Just to give some examples of what I mean:

`minimum`:

> <https://github.com/JuliaLang/julia/blob/48f942bdd659ae55d7d3e34dcf15dbb8bd871d71/base/reduce.jl#L562-L602>

`findall` on a `BitArray`:

> <https://github.com/JuliaLang/julia/blob/48f942bdd659ae55d7d3e34dcf15dbb8bd871d71/base/bitarray.jl#L1612-L1638>

> [@Tamas\_Papp](#):
>
> I would say that loops are usually one of the fastest solution in Julia, and the only reason _not_ to apply them is code clarity: more abstract code is usually easier to understand.

I would disagree with that. There are many optimization opportunities over looping in memory order and in quite a few cases Base code goes that extra step to squeeze out a bit more performance.

---

<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:** [April 19, 2020, 4:56am UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/19 "2020-04-19T04:56:43Z")

</div>

The `findall(::BitArray)` optimization really shines here compared to the iterator-based `findall`, despite the need to allocate an intermediate `BitArray`:

```julia
julia> @btime findall(A .> 0.1) setup=(A=rand(1000))
  1.833 μs (4 allocations: 11.30 KiB)

julia> @btime findall(>(0.1), A) setup=(A=rand(1000))
  8.533 μs (14 allocations: 16.55 KiB)

```

It’s faster for almost every case I tested (the only exception being small arrays where few elements satisfy the condition). The advantage likely boils down to SIMD execution of the comparison, and avoiding the need to repeatedly grow/copy the output array. It’d be great for the iterator-based implementation to specialize on strided numeric arrays to take advantage of SIMD.

---

<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:** [April 20, 2020, 5:02pm UTC](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780/20 "2020-04-20T17:02:28Z")

</div>

The iterator-based approach would be sped up significantly by resolving issues [#32035](https://github.com/JuliaLang/julia/pull/32035) and [#32320](https://github.com/JuliaLang/julia/pull/32320), but those haven’t been touched since last spring.

[Next page](https://discourse.julialang.org/t/how-to-obtain-indices-of-an-array-satisfying-boolean-condition/37780.md?page=2)
