# Reducing monthly data to yearly

**URL:** <https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087>\
**Category:** General Usage\
**Tags:** question\
**Created:** [August 22, 2023, 5:22pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087 "2023-08-22T17:22:47Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![yvikhlya](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yvikhlya/32/3753_2.png) [@yvikhlya](https://discourse.julialang.org/u/yvikhlya)\
**Post date:** [August 22, 2023, 5:22pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/1 "2023-08-22T17:22:47Z")

</div>

Hello All. I have a geospatial data in netCDF format with monthly frequency. Time variable is an array of `DateTime` objects. I want a selected variable `var[LAT, LON, DEPTH, MONTH]` to be reduced to `var[LAT, LON, DEPTH, YEAR]`, where the value for each `YEAR` is an average of all months of this year. I don’t need to write data back into netCDF. What is the most efficient way to do this in Julia?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [August 22, 2023, 6:24pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/2 "2023-08-22T18:24:45Z")

</div>

> [@yvikhlya](#):
>
> I want a selected variable `var[LAT, LON, DEPTH, MONTH]` to be reduced to `var[LAT, LON, DEPTH, YEAR]`

Have you tried just writing a loop? e.g.

```julia
newvar = zeros(eltype(var), size(var,1), size(var,2), size(var,3), nyears)
count = zeros(Int, size(newvar))
for i in CartesianIndices(var)
    inew = CartesianIndex(i[1], i[2], i[3], month2year(i[4]))
    newvar[inew] += var[i]
    count[inew] += 1
end
newvar ./= count # mean

```

where `nyears` and `month2year` are defined appropriately.

---

<div class="post-metadata">

**Author:** ![yvikhlya](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yvikhlya/32/3753_2.png) [@yvikhlya](https://discourse.julialang.org/u/yvikhlya)\
**Post date:** [August 22, 2023, 6:37pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/3 "2023-08-22T18:37:09Z")

</div>

Yes, I can do it a straightforward way with a loop. I thought if any package already has some function like `coarsen` in xarray, or some one liner is possible.

---

<div class="post-metadata">

**Author:** ![dlakelan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlakelan/32/8491_2.png) [@dlakelan](https://discourse.julialang.org/u/dlakelan)\
**Post date:** [August 23, 2023, 4:06am UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/4 "2023-08-23T04:06:46Z")

</div>

Convert to a DataFrame, and use DataFramesMeta to group by year and avg over the months, with `@combine`

---

<div class="post-metadata">

**Author:** ![Rudi79](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rudi79/32/3884_2.png) [@Rudi79](https://discourse.julialang.org/u/Rudi79)\
**Post date:** [August 23, 2023, 9:15am UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/5 "2023-08-23T09:15:14Z")

</div>

A solution without DataFramesMeta could look like

```julia
using DataFrames, Dates, Statistics
d = DataFrame(month = now()-Year(1):Month(1):now(), lat = rand(13), lon = rand(13), depth = rand(13))
vars = [:lat, :lon, :depth]
d[!,:year] = floor.(d.month, Year)
r = combine(groupby(d, :year), vars .=> mean)

```

---

<div class="post-metadata">

**Author:** ![yvikhlya](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yvikhlya/32/3753_2.png) [@yvikhlya](https://discourse.julialang.org/u/yvikhlya)\
**Post date:** [August 23, 2023, 3:57pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/6 "2023-08-23T15:57:09Z")

</div>

My data is a huge 4d array. I don’t think a data frame is an appropriate data structure for it.

---

<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 23, 2023, 10:04pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/8 "2023-08-23T22:04:54Z")

</div>

maybe you should explain precisely the structure of your data.  
In the meantime you will have some attempts to interpret, among which I add mine, imagining a matrix structure sorted by the last column: the date.

```julia
[mean(m[1+(i-1)*12:12+(i-1)*12,:],dims=1) for i in 1:Int(size(m,1)/12)]

```

---

<div class="post-metadata">

**Author:** ![Fliks](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fliks/32/2494_2.png) [@Fliks](https://discourse.julialang.org/u/Fliks)\
**Post date:** [August 23, 2023, 10:16pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/9 "2023-08-23T22:16:56Z")

</div>

You could use the YAXArrays package for that. See [Estimating statistics per month · Issue #217 · JuliaDataCubes/YAXArrays.jl · GitHub](https://github.com/JuliaDataCubes/YAXArrays.jl/issues/217) for an example of doing time aggregation. Beware, that this example will only work on Version 0.4.We recently switched the package to use DimensionalData as the array type and need to polish some edges.

---

<div class="post-metadata">

**Author:** ![yvikhlya](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yvikhlya/32/3753_2.png) [@yvikhlya](https://discourse.julialang.org/u/yvikhlya)\
**Post date:** [August 23, 2023, 10:22pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/10 "2023-08-23T22:22:55Z")

</div>

This does exactly what I need, thanks! (How could I forget about comprehensions??)

---

<div class="post-metadata">

**Author:** ![yvikhlya](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yvikhlya/32/3753_2.png) [@yvikhlya](https://discourse.julialang.org/u/yvikhlya)\
**Post date:** [August 23, 2023, 10:25pm UTC](https://discourse.julialang.org/t/reducing-monthly-data-to-yearly/103087/11 "2023-08-23T22:25:23Z")

</div>

I’ll look at YAXarrays, thanks. I am an active python `xarray` user, who tries to port some of its functionality to Julia in a domain specific way.
