means#
Calculate daily, monthly, yearly, etc. means
This module was written by Matthias Cuntz while at Department of Computational Hydrosystems, Helmholtz Centre for Environmental Research - UFZ, Leipzig, Germany, and continued while at Institut National de Recherche pour l’Agriculture, l’Alimentation et l’Environnement (INRAE), Nancy, France.
- copyright:
Copyright 2013-2022 Matthias Cuntz, see AUTHORS.rst for details.
- license:
MIT License, see LICENSE for details.
The following functions are provided
|
Calculate daily, monthly, yearly, etc. |
- History
Written Jul 2013 by Matthias Cuntz (mc (at) macu (dot) de)
Added meanday, Jul 2013, Matthias Cuntz
Added max and min, Apr 2014, Matthias Cuntz
Added onlydat and meanmonth, Jun 2015, Matthias Cuntz
Added seasonal, Oct 2018, Matthias Cuntz
Bug in minute averaging: compared minutes to hours, Jun 2019, Matthias Cuntz
Added half_hour, inspired by Robin Leucht for UFZ level1 data; did not take retrospective keyword but added Note for this case, Jun 2019, Matthias Cuntz
Use pyjams datetime, Jul 2022, Matthias Cuntz
More possible date formats, Jul 2022, Matthias Cuntz
Rename seasonal to seasonalday, Jul 2022, Matthias Cuntz
Add seasonalmonth, Jul 2022, Matthias Cuntz
Add seasonalmeanday, Jul 2022, Matthias Cuntz
Use second precision for output dates, Aug 2024, Matthias Cuntz
- means(date, dat, year=False, month=False, day=False, hour=False, half_hour=False, minute=False, meanday=False, meanmonth=False, seasonalday=False, seasonalmonth=False, seasonalmeanday=False, sum=False, max=False, min=False, onlydat=False, **kwargs)[source]#
Calculate daily, monthly, yearly, etc. means of data
dat will be averaged over columns, i.e. assuming that the first dimension is the time dimension.
If no keyword argument is given, the mean will be over the whole first column.
date can be either string or datetime object of Python, numpy, cftime, or pyjams, which will be interpreted by pyjams.date2num; or date can be a numeric value, which will be interpreted by pyjams.num2date; any extra keyword argument will be passed to the appropriate datetime routine. Returned dates will be in same format as incoming dates.
- Parameters:
date (1D array with dates) – Can either be strings or datetime objects of Python, cftime or pyjams, which will be interpreted by pyjams.date2num, or it can be a numeric value, which will be interpreted by pyjams.num2date. date should be centred on the input time period, i.e. half-hourly data should have dates at 15 min and 45 min of each hour, for example.
dat (ND (masked-)array)
year (bool, optional) – If True, return annual means
month (bool, optional) – If True, return monthly means
day (bool, optional) – If True, return daily means
hour (bool, optional) – If True, return hourly means
half_hour (bool, optional) – If True, return half-hourly means
minute (bool, optional) – If True, return minute means. Note that this can take very long.
meanday (bool, optional) – If True, return one mean daily cycle
meanmonth (bool, optional) – If True, return mean monthly cycle
seasonalday (bool, optional) – If True, return daily means seasonal cycle
seasonalmonth (bool, optional) – Same as meanmonth. If True, return mean monthly cycle
seasonalmeanday (bool, optional) – If True, return one mean daily cycle per month
sum (bool, optional) – If True, calculate sums instead of means
max (bool, optional) – If True, calculate maxima instead of means
min (bool, optional) – If True, calculate minima instead of means
onlydat (bool, optional) – If True, return only meandat, else return [outdate, meandat]
**kwargs (dict, optional) – Any other keyword argument will be passed to either pyjams.date2num or pyjams.num2date depending on type of date
- Returns:
centred date on year, month, day, etc.; and averaged data in 1st dimension
- Return type:
outdate, meandat
Notes
outdate is same format as date input. Output meandat is scalar, numpy array, or masked array if needed.
- Returns centred [dates, averages]:
Yearly dates are centred on June 15, 12:00 h
Monthly dates are centred on 15th, 12:00 h
Daily dates are centred on 12:00 h
Hourly dates are centred on 30 min
Half hourly dates are centred on 15 and 45 min
Minute dates are centred on 30 sec
Mean daily dates are centred on 30 min of January 01 of the first year
Mean monthly (seasonal monthly) dates are centred on the 15th of each month at 12:00 h of the first year
Seasonal daily dates are centred on 12:00 h of each day of the first (leap) year
Seasonal mean daily dates are centred on 30 min of each first day of each month of the first year
If meanday/seasonal/meanday/seasonalday/meanmonth/seasonalmonth==True, then all hours/months/days will be written; as a masked-array if hours/days/months are missing.
If seasonalday==True, input data has to be spaced <= days, otherwise consider meanmonth/seasonalmonth.
If input date represent the beginning/end of the time step, the user should add/remove half a time step before using the routine. Otherwise the routine would have to guess the time step, which is error prone. For example, remove 15 minutes by subtracting datetime.timedelta(minutes=15) from datetime, 15./(24.*60.) from Julian dates, or pyjams.date2num(‘2010-01-01 12:15’, units, calendar) - pyjams.date2num(‘2010-01-01 12:00’, units, calendar) from any calendar and units understood by pyjams.datetime or cftime.datetime.
Examples
>>> dates = ['01.01.1990 12:00:00', '01.02.1990 12:00:00', ... '01.03.1990 12:00:00', '01.01.1990 12:10:00', ... '01.01.1990 13:00:00', '01.01.1990 14:00:00'] >>> jdates = date2num(dates, calendar='decimal') >>> x = np.arange(len(jdates)) + 1. >>> odates, xout = means(jdates, x, calendar='decimal') >>> oodates = num2date(odates, calendar='decimal') >>> oodates = oodates.strftime('%Y-%m-%d %H:%M:%S') >>> print(oodates, xout) 1990-01-31 00:00:00 3.5
>>> odates, xout = means(jdates, x, year=True, calendar='decimal') >>> print(xout) [3.5]
>>> odates, xout = means(dates, x, month=True) >>> print(xout) [4. 2. 3.]
>>> odates, xout = means(dates, x, day=True) >>> print(xout) [4. 2. 3.]
>>> odates, xout = means(dates, x, hour=True) >>> print(xout) [2.5 5. 6. 2. 3. ]
>>> odates, xout = means(jdates, x, half_hour=True, calendar='decimal') >>> print(xout) [2.5 5. 6. 2. 3. ]
>>> odates, xout = means(jdates, x, meanday=True, calendar='decimal') >>> print(xout[10:16]) [-- -- 2.5 5.0 6.0 --]
>>> odates, xout = means(jdates, x, meanmonth=True, calendar='decimal') >>> print(xout[0:5]) [4.0 2.0 3.0 -- --]
>>> odates, xout = means(jdates, x, seasonalday=True, calendar='decimal') >>> print(xout[0:5]) [4.0 -- -- -- --]
>>> odates, xout = means(jdates, x, seasonalmonth=True, calendar='decimal') >>> print(xout[0:5]) [4.0 2.0 3.0 -- --]
>>> print(means(jdates, x, month=True, onlydat=True, calendar='decimal')) [4. 2. 3.]
Masked arrays
>>> x = np.ma.array(x, mask=np.zeros(x.size, dtype=bool)) >>> x.mask[0] = True >>> odates, xout = means(jdates, x, calendar='decimal') >>> print(np.around(odates, 1), xout) 1990.1 4.0
>>> odates, xout = means(dates, x, year=True) >>> print(xout) [4.0]
>>> odates, xout = means(dates, x, month=True) >>> print(xout) [5.0 2.0 3.0]
>>> odates, xout = means(jdates, x, day=True, calendar='decimal') >>> print(xout) [5.0 2.0 3.0]
sum
>>> odates, xout = means(jdates, x, sum=True, calendar='decimal') >>> print(np.around(odates, 1), xout) 1990.1 20.0 >>> odates, xout = means(jdates, x, year=True, sum=True, ... calendar='decimal') >>> print(xout) [20.0] >>> odates, xout = means(dates, x, month=True, sum=True) >>> print(xout) [15.0 2.0 3.0] >>> odates, xout = means(jdates, x, day=True, sum=True, calendar='decimal') >>> print(xout) [15.0 2.0 3.0]
max
>>> odates, xout = means(jdates, x, max=True, calendar='decimal') >>> print(np.around(odates, 1), xout) 1990.1 6.0 >>> odates, xout = means(dates, x, year=True, max=True) >>> print(xout) [6.0] >>> odates, xout = means(jdates, x, month=True, max=True, ... calendar='decimal') >>> print(xout) [6.0 2.0 3.0] >>> odates, xout = means(jdates, x, day=True, max=True, calendar='decimal') >>> print(xout) [6.0 2.0 3.0]
min
>>> odates, xout = means(jdates, x, min=True, calendar='decimal') >>> print(np.around(odates, 1), xout) 1990.1 2.0 >>> odates, xout = means(jdates, x, year=True, min=True, ... calendar='decimal') >>> print(xout) [2.0] >>> odates, xout = means(dates, x, month=True, min=True) >>> print(xout) [4.0 2.0 3.0] >>> odates, xout = means(jdates, x, day=True, min=True, calendar='decimal') >>> print(xout) [4.0 2.0 3.0]
2D and masked arrays
>>> x = np.repeat(x,2).reshape((x.size,2)) >>> odates, xout = means(jdates, x, calendar='decimal') >>> print(np.around(odates, 1), xout) 1990.1 [4.0 4.0]
>>> odates, xout = means(jdates, x, year=True, calendar='decimal') >>> print(xout) [[4.0 4.0]]
>>> odates, xout = means(dates, x, month=True) >>> print(xout) [[5.0 5.0] [2.0 2.0] [3.0 3.0]]
>>> odates, xout = means(jdates, x, day=True, calendar='decimal') >>> print(xout) [[5.0 5.0] [2.0 2.0] [3.0 3.0]]