iris.coord_categorisation.add_year(cube,'time')
annmean = cube.aggregated_by(['year'], iris.analysis.MEAN)
ValueError: Invalid Aggregation, aggregated_by() cannot use weights.
# Artificially inflate the cube values for the Februaries which are leap years so when weighted by the 28-day February, results are correct.:
leap_rescale = (29/28-1) * np.logical_and(cube.coord('year')[:].points%4==0, cube.coord('month')[:].points=='Feb') + 1cube.data = cube.data*leap_rescale
# Manually define the month-weights. If your dataset doesn't start in January, may need to be careful.
w = np.array([31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]) def weightmonths(data, w, axis): # This could perhaps be done as a lambda function, which would be more elegant. return np.average(data, axis=axis, weights = w) WeightMonths = iris.analysis.WeightedAggregator('weight_months', weightmonths, w=w)av = cube.aggregated_by('year', WeightMonths, w= w)
import irisimport iris.coord_categorisation
iris.coord_categorisation.add_year(cube, 'time')
iris.coord_categorisation.add_categorised_coord(cube, 'days_in_month', 'time', lambda coord, value: 31 if coord.units.num2date(value).month in [1, 3, 5, 7, 8, 10, 12] else (30 if coord.units.num2date(value).month in [4,6,9,11] else (29 if coord.units.num2date(value).year % 4 ==0 else 28) ))
# Make the aggregated cube, but with improperly calculated averagesav = cube.aggregated_by('year', iris.analysis.MEAN)
# But then manually fix the dataav.data = [np.sum((area_av.data * area_av.coord('days_in_month').points)[area_av.coord('year').points == i]) / np.sum(area_av.coord('days_in_month').points[area_av.coord('year').points == i]) for i in av.coord('year').points]