# How can I easily skip indices in an array?

**URL:** <https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317>\
**Category:** General Usage\
**Tags:** question, indexing, arrays, cartesianindices\
**Created:** [October 25, 2021, 4:46am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317 "2021-10-25T04:46:20Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [October 25, 2021, 4:46am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/1 "2021-10-25T04:46:20Z")

</div>

I have arrays with 2 dimensions. Elements in the arrays are only considered valid for certain values on the indices. For example, consider the arrays `A` and `B` below:

```julia
A = round.(rand(10, 2) .* 100)
A[1:3, 2] .= NaN
B = round.(rand(10, 2) .* 100)
B[1:3, 2] .= NaN

```

If it helps, you can think of the arrays as recording number of people, where the first index represents age groups, and the second index represents education level (HS and college). Younger individuals, say for indices 1 to 3, are too young to have a college degree, so those entries are illegal.

I have to perform operations on the arrays, say `sum` or `prod`. How can I skip the illegal indices for those operations? I can manually keep track of those indices as below

```julia
s = sum(A[a, e]*B[a, e] for a in 1:10, e in 1:2 if (e == 1) || ((e == 2) && (a > 3)))
p = prod(A[a, e]*B[a, e] for a in 1:10, e in 1:2 if (e == 1) || ((e == 2) && (a > 3)))

```

Is there a better, less cumbersome, solution?

---

<div class="post-metadata">

**Author:** ![jishnub](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jishnub/32/33620_2.png) [@jishnub](https://discourse.julialang.org/u/jishnub)\
**Post date:** [October 25, 2021, 5:29am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/2 "2021-10-25T05:29:37Z")

</div>

```julia
julia> sum(x -> isnan(x) ? zero(x) : x, A[i]*B[i] for i in eachindex(A))
65709.0

julia> C = A .* B; sum(@view C[:,1]) + sum(@view C[4:end, 2])
65709.0

```

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [October 25, 2021, 6:26am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/3 "2021-10-25T06:26:46Z")

</div>

The `Missing` type is useful for denoting missing data. Example:

```julia
A = [a ∈ 1:3 && e == 2 ? missing : 100*rand() for a = 1:10, e = 1:2]
B = [a ∈ 1:3 && e == 2 ? missing : 100*rand() for a = 1:10, e = 1:2]
sum(skipmissing(A .* B))

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 25, 2021, 6:51am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/4 "2021-10-25T06:51:13Z")

</div>

Try also Cartesian Indices:

```julia
CI = filter(x -> x ∉ CartesianIndices((1:3,2:2)), CartesianIndices(A))
s = sum(A[I]*B[I] for I in CI)

```

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [October 25, 2021, 7:11am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/5 "2021-10-25T07:11:47Z")

</div>

How can I build the indices on determined sizes of arrays? For example, I defined `A` above to be 10-by-2, if I have variables like `x = 10, y = 2`, how can I build `CI` using those instead?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 25, 2021, 7:20am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/6 "2021-10-25T07:20:13Z")

</div>

> [@amrods](#):
>
> if I have variables like `x = 10, y = 2` , how can I build `CI` using those instead?

Not sure if this is what you ask for:

```julia
CI = filter(x -> x ∉ CartesianIndices((1:3,2:2)), CartesianIndices((1:x,1:y)))

```

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [October 25, 2021, 11:19pm UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/7 "2021-10-25T23:19:56Z")

</div>

Can I use that `CartesianIndices` object to iterate inside a `sum`? something like

```julia
sum(a*e for (a, e) in CI)

```

is it possible?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 25, 2021, 11:25pm UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/8 "2021-10-25T23:25:49Z")

</div>

Please check [this other post](https://discourse.julialang.org/t/slicing-and-merging-of-cartesianindices/61519/2).

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [October 25, 2021, 11:26pm UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/9 "2021-10-25T23:26:55Z")

</div>

got it working like this:

```julia
sum( *(Tuple(i)...) for i in CI)

```

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [October 25, 2021, 11:30pm UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/10 "2021-10-25T23:30:11Z")

</div>

Not on the computer, but this doesn’t work?

```julia
sum(c[1]*c[2] for c in CI)

```

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [October 25, 2021, 11:31pm UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/11 "2021-10-25T23:31:13Z")

</div>

It does! I didn’t think about that way.

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [November 17, 2021, 4:53am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/12 "2021-11-17T04:53:26Z")

</div>

How can I streamline this?

```julia
using StatsBase

L = rand(2, 9, 2, 2, 5)
idx0 = sample(0:1, ProbabilityWeights([0.4, 0.6]), size(L))
L .= L .* idx0

skipzeros = filter(x -> x ∉ findall(L .== 0), CartesianIndices((1:2, 1:9, 1:2, 1:2, 1:5)))

gaek = ones((2, 9, 2, 5))

for idx in skipzeros
    g, a, e, _, k = Tuple(idx)
    t1 = L[g, a, e, 1, k]
    t2 = L[g, a, e, 2, k]
    gaek[g, a, e, k] = t1 + t2
end

gek = ones((2, 2, 5))

for idx in skipzeros
    g, _, e, _, k = Tuple(idx)
    tt1 = gaek[1, :, 1, k]
    tt2 = gaek[2, :, 1, k]
    gek[g, e, k] = sum(tt1 + tt2)
end

```

The problem is that the second loop is too wasteful in the sense that I am assigning the same `tt1`, `tt2` and `gek` several times. Perhaps more specific questions would be: how can I “extract” the `g`, `e`, and `k` components from `skipzeros`?

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [November 17, 2021, 6:13am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/13 "2021-11-17T06:13:14Z")

</div>

> [@amrods](#):
>
> how can I “extract” the `g` , `e` , and `k` components from `skipzeros` ?

You may use `getindex()`, broadcasted for that purpose:

```julia
g = getindex.(skipzeros, 1)
e = getindex.(skipzeros, 3)
k = getindex.(skipzeros, 5)

```

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [November 17, 2021, 6:18am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/14 "2021-11-17T06:18:20Z")

</div>

I was hoping to get another collection of `CartesianIndices`. Is it possible?

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [November 17, 2021, 6:24am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/15 "2021-11-17T06:24:16Z")

</div>

And how can I access all indices along a dimension within the scope of `skipzeros`? For example `gaek[1, :, 1, k]`, but that `:` would be among all the indices in the second dimension that are present in `skipzeros`.

---

<div class="post-metadata">

**Author:** ![rafael.guerra](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rafael.guerra/32/216610_2.png) [@rafael.guerra](https://discourse.julialang.org/u/rafael.guerra)\
**Post date:** [November 17, 2021, 6:37am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/16 "2021-11-17T06:37:06Z")

</div>

> [@amrods](#):
>
> I was hoping to get another collection of `CartesianIndices` . Is it possible?

The following comprehension works but there should be a simpler way:

```julia
CI = [CartesianIndex(i[1],i[3],i[5]) for i in skipzeros]

```

---

<div class="post-metadata">

**Author:** ![amrods](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/amrods/32/2543_2.png) [@amrods](https://discourse.julialang.org/u/amrods)\
**Post date:** [November 17, 2021, 6:40am UTC](https://discourse.julialang.org/t/how-can-i-easily-skip-indices-in-an-array/70317/17 "2021-11-17T06:40:19Z")

</div>

I guess I can also create a generator:

```julia
CI = (CartesianIndex(i[1],i[3],i[5]) for i in skipzeros)

```

any ideas about the other question?
