Weighted Mean#

UXarray supports computing weighted means based on geometric properties such as face areas or edge lengths. In this section of the user guide, we explain how to calculate variable means using unstructured grid geometries as weights. The examples below demonstrate the application of weighted means using grid face areas and grid edge lengths as weights.

import uxarray as ux
import xarray as xr
import cartopy.crs as ccrs

import warnings

warnings.filterwarnings("ignore")

Data#

Data used in this section is a 3-random-variable dataset on a quad hexagon mesh mapped to the edges and faces.

grid_path = "../../test/meshfiles/ugrid/quad-hexagon/grid.nc"
quad_hex_data_path_edge_centered = (
    "../../test/meshfiles/ugrid/quad-hexagon/random-edge-data.nc"
)
quad_hex_data_path_face_centered = (
    "../../test/meshfiles/ugrid/quad-hexagon/random-face-data.nc"
)

uxds_face = ux.open_mfdataset(grid_path, quad_hex_data_path_face_centered)
uxds_edge = ux.open_mfdataset(grid_path, quad_hex_data_path_edge_centered)
(
    uxds_face.uxgrid.plot(line_color="black")
    * uxds_edge["random_data_edge"]
    .plot.points(
        cmap="inferno", size=150, marker="square", clabel=None, tools=["hover"]
    )
    .relabel("Edge Data")
    * uxds_face["random_data_face"]
    .plot.points(
        cmap="inferno", size=150, marker="triangle", clabel=None, tools=["hover"]
    )
    .relabel("Face Data")
).opts(legend_position="top_right")

Weighted Mean based on Face Areas#

Here we first look at the data values on each face and the faces’ respective areas.

uxds_face["random_data_face"].values
array([4.53649447, 3.31347744, 6.20654387, 2.48819151])

We can simply call UxDataArray.weighted_mean() on the UXDataArray to compute the weighted mean. The differences between the weighted mean and the regular mean is small since the area differences across the faces are small.

result = uxds_face["random_data_face"].weighted_mean()
result.values
array(4.13619376)
unweighted_result = uxds_face["random_data_face"].mean()
unweighted_result.values
array(4.13617682)

Weighted Mean Based on Edge Length#

Here we show the similar steps but for edge-centered data and the edge lengths.

uxds_edge["random_data_edge"].values
array([8.01802324, 9.72507993, 6.6914741 , 7.32080453, 3.30975404,
       0.22819568, 0.06583025, 6.35602489, 6.68668242, 9.7668741 ,
       6.30413784, 6.89570468, 1.90836517, 0.57331484, 0.81162917,
       7.37824547, 2.2410142 , 1.46405388, 1.90183779])
uxds_edge.uxgrid.edge_node_distances.data
array([0.00302971, 0.00276214, 0.00244141, 0.00241687, 0.00276214,
       0.00274047, 0.00302971, 0.00244141, 0.00276214, 0.00304932,
       0.00276214, 0.00304932, 0.0024657 , 0.00304932, 0.00276214,
       0.0024657 , 0.00244141, 0.00278363, 0.00304932], dtype=float32)

The differences between weighted and unweighted mean is more drastic (~0.1 value difference) since the edge lengths have a larger variance.

result = uxds_edge["random_data_edge"].weighted_mean()
result.values
array(4.58431796)
unweighted_result = uxds_edge["random_data_edge"].mean()
unweighted_result.values
array(4.61300243)