# Delete the nth frontal of a 3th-order tensor(array)

**URL:** <https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214>\
**Category:** Data\
**Tags:** indexing, arrays\
**Created:** [August 3, 2022, 5:26am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214 "2022-08-03T05:26:53Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![tapyu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tapyu/32/37182_2.png) [@tapyu](https://discourse.julialang.org/u/tapyu)\
**Post date:** [August 3, 2022, 5:26am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/1 "2022-08-03T05:26:53Z")

</div>

Consider the following tensor

```julia
A = reshape(1:24,4,2,3)

```

I want to split it into two elements: B, which is the second frontal of A; and C, which is the remaining elements. Getting B is pretty obvious,

```julia
B = A[:,:,2]

```

But I did not find a clever way to get C since functions such as `popat!()` and `deleteat!()` do not work for high-order arrays.

```julia
popat!(A, :, :, 2)

ERROR: MethodError: no method matching popat!(::Array{Int64, 3}, ::Colon, ::Colon, ::Int64)
Closest candidates are:
  popat!(::Vector, ::Integer, ::Any) at /usr/share/julia/base/array.jl:1296
Stacktrace:
 [1] top-level scope
   @ REPL[58]:1

```

PS: For those who don’t know what a frontal is, here it is:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/7/17100618ad72b64327c39c7e97d5715f5bf25026.png)

---

<div class="post-metadata">

**Author:** ![tapyu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tapyu/32/37182_2.png) [@tapyu](https://discourse.julialang.org/u/tapyu)\
**Post date:** [August 3, 2022, 5:41am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/2 "2022-08-03T05:41:28Z")

</div>

I just found the answer, I didn’t know that it is possible to select an element like that is julia

```julia
B = A[:,:,2]
C = A[:,:,1:end.!=2]

```

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [August 3, 2022, 6:59am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/3 "2022-08-03T06:59:21Z")

</div>

you can also do:

```julia
using InvertedIndices
A[:, :, Not(2)]

```

---

<div class="post-metadata">

**Author:** ![tapyu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tapyu/32/37182_2.png) [@tapyu](https://discourse.julialang.org/u/tapyu)\
**Post date:** [August 4, 2022, 11:22pm UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/4 "2022-08-04T23:22:31Z")

</div>

That is nice but is not built-in ☹

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [August 5, 2022, 12:17am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/5 "2022-08-05T00:17:35Z")

</div>

Nothing wrong with a small dependency. That’s why packages exist.

FWIW InvertedIndices.jl has [no dependencies](https://github.com/JuliaData/InvertedIndices.jl/blob/main/Project.toml) so it really is super light weight.

---

<div class="post-metadata">

**Author:** ![tapyu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tapyu/32/37182_2.png) [@tapyu](https://discourse.julialang.org/u/tapyu)\
**Post date:** [August 5, 2022, 7:20am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/6 "2022-08-05T07:20:15Z")

</div>

That is not the point. IMHO, the built-in solution solve it in a idiomatic way, making `InvertedIndices` unnecessary for this purpose. That is why I put my comment as solution.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [August 5, 2022, 8:35am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/7 "2022-08-05T08:35:44Z")

</div>

`InvertedIndices` is also much slower than the builtin solution:

```julia
julia> A = rand(10, 10, 10);

julia> @btime $A[:, :, (1:end) .!= 2];
  1.457 μs (3 allocations: 7.28 KiB)
julia> @btime $A[:, :, Not(2)];
  4.558 μs (48 allocations: 8.62 KiB)

julia> A = rand(100, 100, 1000);

julia> @btime @view($A[:, :, (1:end) .!= 2]);
  2.210 μs (4 allocations: 12.34 KiB)
julia> @btime @view($A[:, :, Not(2)]);
  272.543 μs (5978 allocations: 179.41 KiB)

```

Not sure if these performance issues are fundamental or can be improved.

---

<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:** [August 5, 2022, 9:02am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/8 "2022-08-05T09:02:56Z")

</div>

> [@aplavin](#):
>
> `@btime @view($A[:, :, (1:end) .!= 2]);`

On my PC the following is even better:

```julia
@btime @view($A[:, :, [1;3:end]]);

```

---

<div class="post-metadata">

**Author:** ![tapyu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tapyu/32/37182_2.png) [@tapyu](https://discourse.julialang.org/u/tapyu)\
**Post date:** [August 5, 2022, 9:37am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/9 "2022-08-05T09:37:50Z")

</div>

The drawback is that you cannot make it generic, while you can change `2` in `A[:, :, (1:end) .!= 2])` by a variable.

---

<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:** [August 5, 2022, 9:53am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/10 "2022-08-05T09:53:44Z")

</div>

I think you can and it’s still faster:

```julia
n = 4
@btime @view($A[:, :, [1:($n-1);($n+1):end]]);

```

---

<div class="post-metadata">

**Author:** ![tapyu](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tapyu/32/37182_2.png) [@tapyu](https://discourse.julialang.org/u/tapyu)\
**Post date:** [August 5, 2022, 10:24am UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/11 "2022-08-05T10:24:45Z")

</div>

Nice/Boa!

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [August 5, 2022, 2:08pm UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/12 "2022-08-05T14:08:44Z")

</div>

Below is a generalization that does not penalize the performance of the solution found by @rafael.guerra

```julia
n=[3,5,9]
@btime @view($A[:, :, deleteat!(collect(1:size($A,ndims($A))),$n)]);

```

here a function that takes advantage of the fact that the set of indices to be excluded is ordered.

```julia
@btime @view($A[:, :, notin($A,$n)]);

function notin(A,n)
    j=1
    k=1
    s=size(A,ndims(A))
    sn=length(n)
    nin=Vector{Int64}(undef, s-sn)
    for i in 1:s
        if i!=n[k]
            nin[j]=i
            j+=1
        else
            if k==sn
                copyto!(nin,j,1:s,i+1,s-i)
                break
            else
                k+=1
            end
        end
    end
    nin
end

```

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [August 5, 2022, 2:33pm UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/13 "2022-08-05T14:33:35Z")

</div>

You should file an issue. I would expect `Not` to be faster.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [August 5, 2022, 2:57pm UTC](https://discourse.julialang.org/t/delete-the-nth-frontal-of-a-3th-order-tensor-array/85214/14 "2022-08-05T14:57:01Z")

</div>

There are unanswered performance issues already, likely related: [Significant performance cost over naively filtering indices · Issue #14 · JuliaData/InvertedIndices.jl · GitHub](https://github.com/JuliaData/InvertedIndices.jl/issues/14) and [Bad performance caused by type unstable `iterate` · Issue #27 · JuliaData/InvertedIndices.jl · GitHub](https://github.com/JuliaData/InvertedIndices.jl/issues/27). I just assumed that performance isn’t a priority for InvertedIndices and so don’t use them myself (but wanted to).
