Climate indices computation package based on Xarray with extensive climate analysis capabilities
Generic statistical analysis tools applicable to any climate variable. These indicators provide distribution fitting, frequency analysis, spell detection, and other statistical methods for comprehensive climate data analysis.
Fundamental statistical measures and aggregation functions for climate data analysis.
def stats(da, op="mean", freq="YS"):
"""
Statistical operation on climate data.
Parameters:
- da: xr.DataArray, input climate data
- op: str, statistical operation ("mean", "max", "min", "std", "var", "sum")
- freq: str, resampling frequency (default "YS")
Returns:
xr.DataArray: Statistical result
"""
def daily_statistics(da, op="mean", freq="YS"):
"""
Daily statistical operations aggregated over time period.
Parameters:
- da: xr.DataArray, daily climate data
- op: str or list, statistical operations to apply
- freq: str, resampling frequency
Returns:
xr.DataArray or xr.Dataset: Daily statistics
"""
def percentiles(da, values=[10, 50, 90], freq="YS"):
"""
Calculate percentiles of climate data.
Parameters:
- da: xr.DataArray, input climate data
- values: list, percentile values to calculate (0-100)
- freq: str, resampling frequency
Returns:
xr.DataArray: Percentile values
"""Statistical distribution fitting and parameter estimation for climate extremes analysis.
def fit(da, dist="norm", freq="YS"):
"""
Fit statistical distribution to climate data.
Parameters:
- da: xr.DataArray, input climate data
- dist: str, distribution name ("norm", "gamma", "weibull", "gev", etc.)
- freq: str, resampling frequency
Returns:
xr.Dataset: Distribution parameters and goodness-of-fit statistics
"""
def return_level(da, return_period=[2, 5, 10, 20, 50, 100], dist="gev", freq="YS"):
"""
Calculate return levels for specified return periods.
Parameters:
- da: xr.DataArray, extreme values data (e.g., annual maxima)
- return_period: list, return periods in years
- dist: str, extreme value distribution ("gev", "weibull", "gamma")
- freq: str, resampling frequency
Returns:
xr.DataArray: Return level estimates
"""
def frequency_analysis(da, threshold, above=True, dist="genpareto", freq="YS"):
"""
Frequency analysis using peaks-over-threshold method.
Parameters:
- da: xr.DataArray, daily climate data
- threshold: float, threshold for extreme event detection
- above: bool, whether to analyze values above (True) or below (False) threshold
- dist: str, distribution for threshold exceedances ("genpareto", "exp")
- freq: str, resampling frequency
Returns:
xr.Dataset: Distribution parameters and return level estimates
"""
def standardized_index(da, distribution="gamma", freq="MS", window=1):
"""
Calculate standardized index (e.g., SPI, SPEI).
Parameters:
- da: xr.DataArray, climate data (e.g., precipitation for SPI)
- distribution: str, distribution for fitting ("gamma", "pearson3", "norm")
- freq: str, resampling frequency (typically "MS" for monthly)
- window: int, accumulation window in months
Returns:
xr.DataArray: Standardized index values
"""Consecutive event detection and characterization for drought, heat waves, and other persistent conditions.
def spell_length(da, threshold, op=operator.ge, freq="YS"):
"""
Calculate spell lengths for threshold exceedances.
Parameters:
- da: xr.DataArray, daily climate data
- threshold: float, threshold value for spell detection
- op: callable, comparison operator (operator.ge, operator.le, etc.)
- freq: str, resampling frequency
Returns:
xr.DataArray: Spell length statistics (max, mean, total)
"""
def threshold_count(da, threshold, op=operator.ge, freq="YS"):
"""
Count threshold exceedances over time period.
Parameters:
- da: xr.DataArray, daily climate data
- threshold: float, threshold value
- op: callable, comparison operator (default operator.ge for >=)
- freq: str, resampling frequency
Returns:
xr.DataArray: Count of threshold exceedances
"""
def run_length(da, window=1, freq="YS"):
"""
Run length encoding for consecutive identical values.
Parameters:
- da: xr.DataArray, input data (typically boolean)
- window: int, minimum run length to consider
- freq: str, resampling frequency
Returns:
xr.DataArray: Run length statistics
"""
def longest_run(da, threshold, op=operator.ge, freq="YS"):
"""
Find longest consecutive run meeting condition.
Parameters:
- da: xr.DataArray, daily climate data
- threshold: float, threshold value
- op: callable, comparison operator
- freq: str, resampling frequency
Returns:
xr.DataArray: Length of longest run
"""Trend analysis and change point detection for climate change assessment.
def trend_slope(da, freq="YS"):
"""
Calculate linear trend slope using least squares regression.
Parameters:
- da: xr.DataArray, time series climate data
- freq: str, resampling frequency for trend calculation
Returns:
xr.DataArray: Trend slope values (units per time)
"""
def mann_kendall_trend(da, alpha=0.05, freq="YS"):
"""
Mann-Kendall trend test for monotonic trends.
Parameters:
- da: xr.DataArray, time series climate data
- alpha: float, significance level (default 0.05)
- freq: str, resampling frequency
Returns:
xr.Dataset: Trend statistics (tau, p-value, slope)
"""
def change_point_detection(da, method="pettitt", freq="YS"):
"""
Detect change points in climate time series.
Parameters:
- da: xr.DataArray, time series climate data
- method: str, detection method ("pettitt", "buishand", "snht")
- freq: str, resampling frequency
Returns:
xr.Dataset: Change point statistics and location
"""Advanced extreme value statistics for climate risk assessment.
def block_maxima(da, block_size="YS"):
"""
Extract block maxima for extreme value analysis.
Parameters:
- da: xr.DataArray, daily climate data
- block_size: str, size of blocks for maxima extraction ("YS", "MS", "QS")
Returns:
xr.DataArray: Block maximum values
"""
def peaks_over_threshold(da, threshold, min_separation=1):
"""
Extract peaks over threshold for extreme value analysis.
Parameters:
- da: xr.DataArray, daily climate data
- threshold: float, threshold value for peak detection
- min_separation: int, minimum separation between peaks in days
Returns:
xr.DataArray: Peak values above threshold
"""
def extreme_events(da, threshold, duration=1, freq="YS"):
"""
Identify and characterize extreme events.
Parameters:
- da: xr.DataArray, daily climate data
- threshold: float, threshold for extreme event definition
- duration: int, minimum duration for event detection
- freq: str, resampling frequency
Returns:
xr.Dataset: Event characteristics (count, duration, intensity)
"""import xarray as xr
import xclim.generic as xcg
import operator
# Load climate data
ds = xr.tutorial.open_dataset("air_temperature")
tas = ds.air.rename("tas")
# Basic statistics
annual_mean = xcg.stats(tas, op="mean", freq="YS")
annual_max = xcg.stats(tas, op="max", freq="YS")
temp_percentiles = xcg.percentiles(tas, values=[5, 25, 75, 95], freq="YS")# Fit distribution to annual maxima
annual_max = xcg.stats(tas, op="max", freq="YS")
fit_result = xcg.fit(annual_max, dist="gev")
# Calculate return levels
return_levels = xcg.return_level(
annual_max,
return_period=[2, 5, 10, 25, 50, 100],
dist="gev"
)# Heat wave analysis (assuming temperature in Celsius)
heat_threshold = 30.0 # 30°C
heat_spells = xcg.spell_length(
tas,
threshold=heat_threshold,
op=operator.ge,
freq="YS"
)
# Count hot days
hot_days = xcg.threshold_count(
tas,
threshold=heat_threshold,
op=operator.ge,
freq="YS"
)
# Find longest heat wave
longest_heat_wave = xcg.longest_run(
tas,
threshold=heat_threshold,
op=operator.ge,
freq="YS"
)# Calculate Standardized Precipitation Index (SPI)
pr = ds.precip.rename("pr") if "precip" in ds else None
if pr is not None:
spi_3 = xcg.standardized_index(
pr,
distribution="gamma",
freq="MS",
window=3 # 3-month SPI
)
spi_12 = xcg.standardized_index(
pr,
distribution="gamma",
freq="MS",
window=12 # 12-month SPI
)# Calculate temperature trends
temp_trend = xcg.trend_slope(tas, freq="YS")
# Mann-Kendall trend test
mk_result = xcg.mann_kendall_trend(tas, alpha=0.05, freq="YS")
significant_trends = mk_result.p_value < 0.05
# Change point detection
change_points = xcg.change_point_detection(tas, method="pettitt", freq="YS")# Extract annual maxima
annual_extremes = xcg.block_maxima(tas, block_size="YS")
# Peaks over threshold analysis
threshold = tas.quantile(0.95) # 95th percentile threshold
peaks = xcg.peaks_over_threshold(tas, threshold=threshold, min_separation=3)
# Characterize extreme events
extreme_events = xcg.extreme_events(
tas,
threshold=threshold,
duration=3, # At least 3 days
freq="YS"
)