Coverage for src/scores/continuous/standard_impl.py: 100%
32 statements
« prev ^ index » next coverage.py v7.3.2, created at 2024-02-28 12:51 +1100
« prev ^ index » next coverage.py v7.3.2, created at 2024-02-28 12:51 +1100
1"""
2This module contains standard methods which may be used for continuous scoring
3"""
5import xarray as xr
7import scores.functions
8import scores.utils
9from scores.typing import FlexibleArrayType, FlexibleDimensionTypes
12def mse(
13 fcst: FlexibleArrayType,
14 obs: FlexibleArrayType,
15 reduce_dims: FlexibleDimensionTypes = None,
16 preserve_dims: FlexibleDimensionTypes = None,
17 weights: xr.DataArray = None,
18 angular: bool = False,
19):
20 """Calculates the mean squared error from forecast and observed data.
22 Dimensional reduction is not supported for pandas and the user should
23 convert their data to xarray to formulate the call to the metric. At
24 most one of reduce_dims and preserve_dims may be specified.
25 Specifying both will result in an exception.
27 Args:
28 fcst (Union[xr.Dataset, xr.DataArray, pd.Dataframe, pd.Series]):
29 Forecast or predicted variables in xarray or pandas.
30 obs (Union[xr.Dataset, xr.DataArray, pd.Dataframe, pd.Series]):
31 Observed variables in xarray or pandas.
32 reduce_dims (Union[str, Iterable[str]): Optionally specify which
33 dimensions to reduce when calculating MSE. All other dimensions
34 will be preserved.
35 preserve_dims (Union[str, Iterable[str]): Optionally specify which
36 dimensions to preserve when calculating MSE. All other dimensions
37 will be reduced. As a special case, 'all' will allow all dimensions
38 to be preserved. In this case, the result will be in the same
39 shape/dimensionality as the forecast, and the errors will be
40 the squared error at each point (i.e. single-value comparison
41 against observed), and the forecast and observed dimensions
42 must match precisely.
43 weights: Optionally provide an array for weighted averaging (e.g. by area, by latitude,
44 by population, custom)
45 angular: specifies whether `fcst` and `obs` are angular
46 data (e.g. wind direction). If True, a different function is used
47 to calculate the difference between `fcst` and `obs`, which
48 accounts for circularity. Angular `fcst` and `obs` data should be in
49 degrees rather than radians.
52 Returns:
53 Union[xr.Dataset, xr.DataArray, pd.Dataframe, pd.Series]: An object containing
54 a single floating point number representing the mean absolute
55 error for the supplied data. All dimensions will be reduced.
56 Otherwise: Returns an object representing the mean squared error,
57 reduced along the relevant dimensions and weighted appropriately.
58 """
59 if angular:
60 error = scores.functions.angular_difference(fcst, obs)
61 else:
62 error = fcst - obs
63 squared = error * error
64 squared = scores.functions.apply_weights(squared, weights)
66 if preserve_dims or reduce_dims:
67 reduce_dims = scores.utils.gather_dimensions(
68 fcst.dims, obs.dims, reduce_dims=reduce_dims, preserve_dims=preserve_dims
69 )
71 if reduce_dims is not None:
72 _mse = squared.mean(dim=reduce_dims)
73 else:
74 _mse = squared.mean()
76 return _mse
79def rmse(
80 fcst: FlexibleArrayType,
81 obs: FlexibleArrayType,
82 reduce_dims: FlexibleDimensionTypes = None,
83 preserve_dims: FlexibleDimensionTypes = None,
84 weights: xr.DataArray = None,
85 angular: bool = False,
86) -> FlexibleArrayType:
87 """Calculate the Root Mean Squared Error from xarray or pandas objects.
89 A detailed explanation is on [Wikipedia](https://en.wikipedia.org/wiki/Root-mean-square_deviation)
92 Dimensional reduction is not supported for pandas and the user should
93 convert their data to xarray to formulate the call to the metric.
94 At most one of `reduce_dims` and `preserve_dims` may be specified.
95 Specifying both will result in an exception.
98 Args:
99 fcst: Forecast
100 or predicted variables in xarray or pandas.
101 obs: Observed
102 variables in xarray or pandas.
103 reduce_dims: Optionally specify which dimensions to reduce when
104 calculating RMSE. All other dimensions will be preserved.
105 preserve_dims: Optionally specify which dimensions to preserve
106 when calculating RMSE. All other dimensions will be reduced.
107 As a special case, 'all' will allow all dimensions to be
108 preserved. In this case, the result will be in the same
109 shape/dimensionality as the forecast, and the errors will be
110 the absolute error at each point (i.e. single-value comparison
111 against observed), and the forecast and observed dimensions
112 must match precisely.
113 weights: Optionally provide an array for weighted averaging (e.g. by area, by latitude,
114 by population, custom)
115 angular: specifies whether `fcst` and `obs` are angular
116 data (e.g. wind direction). If True, a different function is used
117 to calculate the difference between `fcst` and `obs`, which
118 accounts for circularity. Angular `fcst` and `obs` data should be in
119 degrees rather than radians.
121 Returns:
122 An object containing
123 a single floating point number representing the root mean squared
124 error for the supplied data. All dimensions will be reduced.
125 Otherwise: Returns an object representing the root mean squared error,
126 reduced along the relevant dimensions and weighted appropriately.
128 """
129 _mse = mse(
130 fcst=fcst, obs=obs, reduce_dims=reduce_dims, preserve_dims=preserve_dims, weights=weights, angular=angular
131 )
133 _rmse = pow(_mse, (1 / 2))
135 return _rmse
138def mae(
139 fcst: FlexibleArrayType,
140 obs: FlexibleArrayType,
141 reduce_dims: FlexibleDimensionTypes = None,
142 preserve_dims: FlexibleDimensionTypes = None,
143 weights: xr.DataArray = None,
144 angular: bool = False,
145) -> FlexibleArrayType:
146 """Calculates the mean absolute error from forecast and observed data.
148 A detailed explanation is on [Wikipedia](https://en.wikipedia.org/wiki/Mean_absolute_error)
150 Dimensional reduction is not supported for pandas and the user should
151 convert their data to xarray to formulate the call to the metric.
152 At most one of reduce_dims and preserve_dims may be specified.
153 Specifying both will result in an exception.
155 Args:
156 fcst: Forecast or predicted variables in xarray or pandas.
157 obs: Observed variables in xarray or pandas.
158 reduce_dims: Optionally specify which dimensions to reduce when
159 calculating MAE. All other dimensions will be preserved.
160 preserve_dims: Optionally specify which dimensions to preserve when
161 calculating MAE. All other dimensions will be reduced. As a
162 special case, 'all' will allow all dimensions to be preserved. In
163 this case, the result will be in the same shape/dimensionality
164 as the forecast, and the errors will be the absolute error at each
165 point (i.e. single-value comparison against observed), and the
166 forecast and observed dimensions must match precisely.
167 weights: Optionally provide an array for weighted averaging (e.g. by area, by latitude,
168 by population, custom)
169 angular: specifies whether `fcst` and `obs` are angular
170 data (e.g. wind direction). If True, a different function is used
171 to calculate the difference between `fcst` and `obs`, which
172 accounts for circularity. Angular `fcst` and `obs` data should be in
173 degrees rather than radians.
175 Returns:
176 By default an xarray DataArray containing
177 a single floating point number representing the mean absolute error for the
178 supplied data. All dimensions will be reduced.
180 Alternatively, an xarray structure with dimensions preserved as appropriate
181 containing the score along reduced dimensions
182 """
183 if angular:
184 error = scores.functions.angular_difference(fcst, obs)
185 else:
186 error = fcst - obs
187 ae = abs(error)
188 ae = scores.functions.apply_weights(ae, weights)
190 if preserve_dims is not None or reduce_dims is not None:
191 reduce_dims = scores.utils.gather_dimensions(fcst.dims, obs.dims, reduce_dims, preserve_dims)
193 if reduce_dims is not None:
194 _ae = ae.mean(dim=reduce_dims)
195 else:
196 _ae = ae.mean()
198 # Returns unhinted types if nonstandard types passed in, but this is useful
199 return _ae # type: ignore