The Monet Stats API provides a comprehensive collection of statistical metrics and utilities for atmospheric sciences applications. This reference covers all available functions, their parameters, return values, and use cases.
Monet Stats is organized into several functional modules:
# Import entire library
import monet_stats as ms
# Import specific modules
from monet_stats import contingency_metrics, correlation_metrics
# Import specific functions
from monet_stats import R2, RMSE, POD, FAR
The most recommended way to use Monet Stats with Xarray is via the .monet_stats accessor, which is automatically registered when you import monet_stats.
import monet_stats
import xarray as xr
# Load data
da = xr.open_dataarray("data.nc")
# Use accessor for analysis
climo = da.monet_stats.climatology(freq="month")
mda8 = da.monet_stats.mda8()
import monet_stats as ms
import numpy as np
import xarray as xr
import numpy as np
obs = np.array([1, 2, 3, 4, 5])
mod = np.array([1.1, 2.1, 2.9, 4.1, 4.8])
r2 = ms.R2(obs, mod) # Works with 1D arrays
rmse = ms.RMSE(obs, mod)
# 2D arrays (e.g., spatial fields)
obs_2d = np.random.normal(20, 2, (50, 50))
mod_2d = obs_2d + np.random.normal(0, 1, (50, 50))
fss = ms.FSS(obs_2d, mod_2d, window=5)
import pandas as pd
df = pd.DataFrame({
'observed': np.random.normal(20, 2, 100),
'modeled': np.random.normal(20.5, 2.5, 100),
'station': ['A'] * 50 + ['B'] * 50
})
# Apply metrics by group
results = df.groupby('station').apply(
lambda x: pd.Series({
'RMSE': ms.RMSE(x['observed'], x['modeled']),
'R2': ms.R2(x['observed'], x['modeled'])
})
)
import xarray as xr
obs_da = xr.DataArray(
np.random.normal(20, 2, (10, 10, 365)),
dims=['lat', 'lon', 'time'],
coords={
'lat': range(10),
'lon': range(10),
'time': pd.date_range('2020-01-01', periods=365, freq='D')
}
)
mod_da = obs_da + xr.DataArray(
np.random.normal(0, 1, (10, 10, 365)),
dims=['lat', 'lon', 'time'],
coords=obs_da.coords
)
# Metrics preserve coordinates and dimensions
skill = ms.R2(obs_da, mod_da) # Returns DataArray with same coordinates
Most metrics accept these common parameters:
obs: Observed values (array-like)mod: Modeled/predicted values (array-like)axis: Axis along which to compute metrics (int, optional)nan_policy: How to handle NaN values (‘omit’, ‘propagate’, ‘raise’)Many metrics use threshold parameters for categorical analysis:
minval: Minimum threshold for event definitionmaxval: Maximum threshold for event definition (optional)Spatial metrics often include:
window: Size of spatial window (int)threshold: Event threshold for spatial analysisMost metrics return single scalar values:
r2 = ms.R2(obs, mod) # float
rmse = ms.RMSE(obs, mod) # float
Some metrics return arrays for multi-dimensional input:
# For 2D spatial data
fss = ms.FSS(obs_2d, mod_2d) # float
When using xarray inputs, metrics return DataArrays:
skill = ms.R2(obs_da, mod_da) # DataArray with coordinates
try:
result = ms.R2(obs_1d, mod_2d) # Will raise ValueError
except ValueError as e:
print(f"Shape mismatch: {e}")
# Data with NaN values
obs_with_nan = np.array([1, 2, np.nan, 4])
mod_with_nan = np.array([1.1, 2.1, 3.1, 4.1])
# Functions automatically handle NaN by default
rmse = ms.RMSE(obs_with_nan, mod_with_nan) # Uses valid pairs only
# Invalid types will raise TypeError
try:
result = ms.R2("invalid", "data") # TypeError
except TypeError as e:
print(f"Invalid data type: {e}")
All metrics use NumPy and Xarray vectorized operations for optimal performance. Loop-free implementations ensure maximum speed on modern hardware.
For datasets larger than RAM, monet-stats is fully compatible with Dask. Most metrics are “lazy-aware” and will preserve the Dask computation graph.
# Open large dataset with chunks (Aero Protocol recommended)
ds = xr.open_dataset("large_data.nc", chunks={"time": "auto", "lat": 100, "lon": 100})
obs = xr.open_dataset("obs_data.nc", chunks={"time": "auto", "lat": 100, "lon": 100})
# Metrics stay lazy and don't trigger loading
skill = ms.RMSE(obs.var, ds.var, axis="time")
# Execution only happens on compute()
result = skill.compute()
When using Xarray DataArrays, monet-stats automatically updates the attrs['history'] to track which statistical operations were applied to the data, ensuring scientific reproducibility.
import monet_stats as ms
import numpy as np
# Sample data
obs = np.array([1.0, 2.5, 3.2, 4.8, 5.0])
mod = np.array([1.2, 2.3, 3.5, 4.6, 5.2])
# Error metrics
error_analysis = {
'RMSE': ms.RMSE(obs, mod),
'MAE': ms.MAE(obs, mod),
'MB': ms.MB(obs, mod),
'NMB': ms.NMB(obs, mod),
'NME': ms.NME(obs, mod)
}
def evaluate_model(observed, modeled):
"""Comprehensive model evaluation suite"""
metrics = {
# Error measures
'RMSE': ms.RMSE(observed, modeled),
'MAE': ms.MAE(observed, modeled),
'MB': ms.MB(observed, modeled),
'NMB': ms.NMB(observed, modeled),
# Skill scores
'R2': ms.R2(observed, modeled),
'NSE': ms.NSE(observed, modeled),
'KGE': ms.KGE(observed, modeled),
'IOA': ms.IOA(observed, modeled),
'FAC2': ms.FAC2(observed, modeled),
# Relative measures
'MPE': ms.MPE(observed, modeled),
'NME': ms.NME(observed, modeled)
}
return metrics
# Usage
results = evaluate_model(obs, mod)
for metric, value in results.items():
print(f"{metric}: {value:.4f}")
# Binary event analysis
obs_events = np.array([0, 1, 1, 0, 1, 0, 1, 1, 0, 0])
mod_events = np.array([0, 1, 0, 0, 1, 1, 1, 0, 0, 1])
# Contingency table metrics
contingency_metrics = {
'POD': ms.POD(obs_events, mod_events, threshold=0.5),
'FAR': ms.FAR(obs_events, mod_events, threshold=0.5),
'CSI': ms.CSI(obs_events, mod_events, threshold=0.5),
'HSS': ms.HSS(obs_events, mod_events, threshold=0.5),
'ETS': ms.ETS(obs_events, mod_events, threshold=0.5)
}
The following sections provide auto-generated documentation for each core module based on docstrings.
::: monet_stats.contingency_metrics
::: monet_stats.correlation_metrics
::: monet_stats.error_metrics
::: monet_stats.efficiency_metrics
::: monet_stats.relative_metrics
::: monet_stats.spatial_ensemble_metrics
::: monet_stats.accessor
::: monet_stats.utils_stats
::: monet_stats.distribution_metrics
::: monet_stats.temporal_metrics
::: monet_stats.uncertainty
If you find issues with the API documentation or would like to suggest improvements:
For development documentation, see the Contributing Guide.