# Binning a 2D array

**URL:** <https://discourse.julialang.org/t/binning-a-2d-array/46791>\
**Category:** New to Julia\
**Created:** [September 17, 2020, 4:40pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791 "2020-09-17T16:40:07Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![pnms](https://avatars.discourse-cdn.com/v4/letter/p/7ba0ec/32.png) [@pnms](https://discourse.julialang.org/u/pnms)\
**Post date:** [September 17, 2020, 4:40pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/1 "2020-09-17T16:40:07Z")

</div>

Hi,

I am trying to apply my understanding of image binning in Julia (which at its heart is an operation that needs to be performed on a 2D array) . To that end I created a toy array

```julia
julia> a = rand(range(0,1,step=1),10,10)
10×10 Array{Int64,2}:
 0 1 0 1 1 0 0 0 1 0
 1 0 1 0 1 0 1 1 0 0
 0 1 0 0 1 1 0 1 0 0
 0 0 0 0 0 1 0 1 1 0
 1 1 1 0 0 0 1 0 1 0
 0 0 1 0 0 1 0 0 0 1
 0 0 1 1 0 1 0 0 1 1
 0 1 0 0 1 0 0 0 1 1
 0 1 1 0 0 0 0 1 0 1
 1 0 1 0 1 1 0 1 1 0

```

Now lets say, that I want to bin the data by 2 which in this case, would be a 2x2 kernel to that end I could grasp the logic as follows:

```julia
b=[]
julia> append!(b,a[1]+a[1,1]+a[2]+a[1,2])/2
1-element Array{Float64,1}:
 1.0
julia> b
1-element Array{Any,1}:
 2

```

I guess, where I am stuck is coding a loop that will raster the kernel along a height and width of an input array and return a new array that is a fraction of the input size which in this case would be a 5x5 array.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [September 17, 2020, 4:41pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/2 "2020-09-17T16:41:37Z")

</div>

is there a specific question you wanna ask?

---

<div class="post-metadata">

**Author:** ![pnms](https://avatars.discourse-cdn.com/v4/letter/p/7ba0ec/32.png) [@pnms](https://discourse.julialang.org/u/pnms)\
**Post date:** [September 17, 2020, 4:44pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/3 "2020-09-17T16:44:25Z")

</div>

Yes, i think the specific question is, how do you raster along the dimensions of an array such that the resultatnt array is a fraction of its size. eg. a 10x10 array is now a 5x5 array because each element in the smaller array is an average of a 2x2 kernel.

---

<div class="post-metadata">

**Author:** ![jling](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jling/32/212909_2.png) [@jling](https://discourse.julialang.org/u/jling)\
**Post date:** [September 17, 2020, 5:03pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/4 "2020-09-17T17:03:45Z")

</div>

[ImageTransformations.jl · JuliaImages](https://juliaimages.org/latest/pkgs/transformations/#Examples) there’s existing library that can do this.

To continue where you were originally doing, you want to make a `b` that is `5x5` and then, for each `b[i,j]` you want to look at the corresponding `2x2` in `a`, so, if `i=1, j=1`, you want to look at `a[1:2, 1:2]`; `i=2, j=3` \<= `a[3:4, 5:6]` etc…

---

<div class="post-metadata">

**Author:** ![AndiMD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/andimd/32/6531_2.png) [@AndiMD](https://discourse.julialang.org/u/AndiMD)\
**Post date:** [September 17, 2020, 5:20pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/5 "2020-09-17T17:20:22Z")

</div>

This should work for arbitrary dimensions, and also if the axis length is not divisible by the bin size:

```julia
import Statistics: mean
map( (axes(a) .|> x->Iterators.partition(x,2)) |> x->Iterators.product(x...) ) do idx
       mean(a[idx...])
end

```

---

<div class="post-metadata">

**Author:** ![pnms](https://avatars.discourse-cdn.com/v4/letter/p/7ba0ec/32.png) [@pnms](https://discourse.julialang.org/u/pnms)\
**Post date:** [September 17, 2020, 6:16pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/6 "2020-09-17T18:16:50Z")

</div>

Thanks! I wanted to try this without libs because I wanted to gain a fundamental understanding of the operation.

---

<div class="post-metadata">

**Author:** ![pnms](https://avatars.discourse-cdn.com/v4/letter/p/7ba0ec/32.png) [@pnms](https://discourse.julialang.org/u/pnms)\
**Post date:** [September 17, 2020, 6:17pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/7 "2020-09-17T18:17:35Z")

</div>

Thanks for introducing a new Lib (for me) AndiMD!

---

<div class="post-metadata">

**Author:** ![tomerarnon](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomerarnon/32/3170_2.png) [@tomerarnon](https://discourse.julialang.org/u/tomerarnon)\
**Post date:** [September 17, 2020, 7:44pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/8 "2020-09-17T19:44:52Z")

</div>

My suggestion is to use `CartesianIndices` to iterate over `a`. Note that you can create ranges of `CartesianIndex`es, e.g.

```julia
julia> CartesianIndex(1, 1):CartesianIndex(2, 2)
2×2 CartesianIndices{2,Tuple{UnitRange{Int64},UnitRange{Int64}}}:
 CartesianIndex(1, 1) CartesianIndex(1, 2)
 CartesianIndex(2, 1) CartesianIndex(2, 2)

```

which will probably get you pretty far. As an added tip, arithmetic woks on `CartesianIndex` as though it were a scalar, as do functions like `one`, `zero`, etc, which you may find yourself needing.

---

<div class="post-metadata">

**Author:** ![contradict](https://avatars.discourse-cdn.com/v4/letter/c/ac91a4/32.png) [@contradict](https://discourse.julialang.org/u/contradict)\
**Post date:** [September 17, 2020, 10:10pm UTC](https://discourse.julialang.org/t/binning-a-2d-array/46791/9 "2020-09-17T22:10:25Z")

</div>

If you always want a power-of-2 bin, repeated application of this works:

```julia
bin2(a) = a[1:2:end-1, 1:2:end-1] .+ a[2:2:end, 1:2:end-1] .+ a[1:2:end-1, 2:2:end] .+ a[2:2:end, 2:2:end]

```
