|
| 1 | +using DimensionalData |
| 2 | +using Dates |
| 3 | +using Statistics |
| 4 | +const DD = DimensionalData |
| 5 | + |
| 6 | +# # Basics: DateTime operations we can use for grouping |
| 7 | + |
| 8 | +# First lets look at the kind of functions that can be used to group `DateTime`. |
| 9 | +# Other types will follow the same principles, but are usually simpler. |
| 10 | + |
| 11 | +# Create a demo `DateTime` range |
| 12 | +tempo = range(DateTime(2000), step=Hour(1), length=365*24*2) |
| 13 | + |
| 14 | +# Now lets see how some common functions work. |
| 15 | + |
| 16 | +# The `hour` function will transform values to hour of the day - the integers `0:23` |
| 17 | + |
| 18 | +# ### hour |
| 19 | +hour.(tempo) |
| 20 | + |
| 21 | +# These do similar things with other time periods |
| 22 | + |
| 23 | +# ### dayofweek |
| 24 | +dayofweek.(tempo) |
| 25 | + |
| 26 | +# ### month |
| 27 | +month.(tempo) |
| 28 | + |
| 29 | +# ### dayofyear |
| 30 | +dayofyear.(tempo) |
| 31 | + |
| 32 | +# ## Tuple grouping |
| 33 | + |
| 34 | +# Some functions return a tuple - we can also use tuples for grouping. |
| 35 | +# They are sorted by the left to right values. |
| 36 | + |
| 37 | +# ### yearmonth |
| 38 | +yearmonth.(tempo) |
| 39 | + |
| 40 | +# We can creat our own anonymous function that return tuples |
| 41 | +yearday(x) = year(x), dayofyear(x) |
| 42 | + |
| 43 | +yearhour(x) = year(x), hour(x) |
| 44 | + |
| 45 | +# And you can probably guess what they do: |
| 46 | +yearday.(tempo) |
| 47 | + |
| 48 | +# All of these functions can be used in `groupby` on `DateTime` objects. |
| 49 | + |
| 50 | +# # Practical example: grouping by season |
| 51 | + |
| 52 | +# ### TODOS: We will need several functions. |
| 53 | + |
| 54 | +# # groupby operations |
| 55 | +# Here we use the same time functions from above |
| 56 | + |
| 57 | +ds = rand(X(1:0.01:2), Ti(tempo)) |
| 58 | + |
| 59 | +# ## select by month, days, years and seasons |
| 60 | +# ### TODO, how do we select month 1 or 2, and even a group of them, i.e. [1,3,5]? Same for days, years and seasons. |
| 61 | +mean.(groupby(ds, Ti=>Bins(month, 1:2))) |
| 62 | +mean.(groupby(ds, Ti=>Bins(month, [1, 3, 5]))) |
| 63 | +mean.(groupby(ds, Ti => season(; start=December))) |
| 64 | +mean.(groupby(ds, Ti => Bins(dayofyear, intervals(1:8:370)))) |
| 65 | +mean.(groupby(ds, Ti => Bins(yearday, [[1,2,3], [4,5,6]], labels=x -> join(string.(x), ',')))) |
| 66 | +mean.(groupby(ds, Ti => week)) |
| 67 | +mean.(groupby(ds, Ti => hours(12; start=6, labels=x -> 6 in x ? :night : :day))) |
| 68 | +mean.(groupby(ds, Ti => dims(ds, Ti))) |
| 69 | + |
| 70 | +# ### TODO, we need a new function that can return DJF (Dec-Jan-Feb), MAM (Mar-Apr-May)... etc. |
| 71 | +# THIS IS HARD. We need a succinct way to select around the end-start of the year. |
| 72 | + |
| 73 | +# is combining month from different years |
| 74 | +mean.(groupby(ds, Ti=>month)) |
| 75 | + |
| 76 | +# Use three-month bins. The 13 is the open side of the last interval. |
| 77 | +mean.(groupby(ds, Ti=>Bins(yearmonth, intervals(1:3:12)))) |
| 78 | + |
| 79 | +mean.(groupby(ds, Ti=>Bins(month, 4))) # is combining month from different years |
| 80 | + |
| 81 | +# |
| 82 | +mean.(groupby(ds, Ti=>year)) |
| 83 | + |
| 84 | +# |
| 85 | +mean.(groupby(ds, Ti=>yearmonth)) |
| 86 | + |
| 87 | +# |
| 88 | +mean.(groupby(ds, Ti=>hour)) |
| 89 | + |
| 90 | +# |
| 91 | +mean.(groupby(ds, Ti=>Dates.hour12)) |
| 92 | + |
| 93 | +# ### TODO. How do could we incorporate resample? Let's say if we have hour resolution I want to resample every 3,6,12.. hours? |
| 94 | +mean.(groupby(ds, Ti=>Bins(yearhour, intervals(1:3:24)))) # it will combine the same day from different year. |
| 95 | + |
| 96 | +mean.(groupby(ds, Ti=>dayofyear)) # it will combine the same day from different year. |
| 97 | + |
| 98 | +# |
| 99 | +mean.(groupby(ds, Ti=>yearmonthday)) # this does the a daily mean aggregation. |
| 100 | + |
| 101 | +# |
| 102 | +mean.(groupby(ds, Ti=>yearmonth)) # this does a monthly mean aggregation |
| 103 | + |
| 104 | +# |
| 105 | +mean.(groupby(ds, Ti=>yearday)) # this does a daily mean aggregation |
| 106 | + |
| 107 | +mean.(groupby(ds, Ti=>Bins(yearhour, 12))) # this does a daily mean aggregation |
| 108 | + |
| 109 | +# ### TODO. Similar to the hourly resample, how do we do it for more than 1 day, let's say 8daily? |
| 110 | +mean.(groupby(ds, Ti=>Bins(dayofyear, map(x -> x:x+7, 1:8:370)))) |
| 111 | + |
| 112 | +# ### TODO: Group by Dims. This should include the rasters input sampling. |
| 113 | +mean.(groupby(ds, dims(ds, Ti))) |
| 114 | + |
| 115 | +# ## Apply custom function (i.e. normalization) to grouped output. |
0 commit comments