-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathaveraging.py
140 lines (107 loc) · 3.8 KB
/
averaging.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# <h1>Table of Contents<span class="tocSkip"></span></h1>
# <div class="toc"><ul class="toc-item"></ul></div>
# <h1>Table of Contents<span class="tocSkip"></span></h1>
# <div class="toc"><ul class="toc-item"></ul></div>
'''
Weighted averaging for xarray data sets, based on:
https://github.com/pydata/xarray/issues/422#issuecomment-140823232
Authors
-------
Mathias Hauser (https://github.com/mathause)
Xylar Asay-Davis
'''
import xarray
def xarray_average(data, dim=None, weights=None, **kwargs): # {{{
"""
weighted average for xarray objects
Parameters
----------
data : Dataset or DataArray
the xarray object to average over
dim : str or sequence of str, optional
Dimension(s) over which to apply average.
weights : DataArray
weights to apply. Shape must be broadcastable to shape of data.
kwargs : dict
Additional keyword arguments passed on to internal calls to ``mean``
or ``sum`` (performed on the data set or data array but *not* those
performed on the weights)
Returns
-------
reduced : Dataset or DataArray
New xarray object with average applied to its data and the indicated
dimension(s) removed.
Authors
-------
Mathias Hauser (https://github.com/mathause)
Xylar Asay-Davis
"""
if isinstance(data, xarray.Dataset):
return _average_ds(data, dim, weights, **kwargs)
elif isinstance(data, xarray.DataArray):
return _average_da(data, dim, weights, **kwargs)
else:
raise ValueError("date must be an xarray Dataset or DataArray")
# }}}
def _average_da(da, dim=None, weights=None, **kwargs): # {{{
"""
weighted average for DataArrays
Parameters
----------
dim : str or sequence of str, optional
Dimension(s) over which to apply average.
weights : DataArray
weights to apply. Shape must be broadcastable to shape of self.
kwargs : dict
Additional keyword arguments passed on to internal calls to ``mean``
or ``sum`` (performed on the data set or data array but *not* those
performed on the weights)
Returns
-------
reduced : DataArray
New DataArray with average applied to its data and the indicated
dimension(s) removed.
Authors
-------
Mathias Hauser (https://github.com/mathause)
Xylar Asay-Davis
"""
if weights is None:
return da.mean(dim, **kwargs)
else:
if not isinstance(weights, xarray.DataArray):
raise ValueError("weights must be a DataArray")
# if NaNs are present, we need individual weights
if da.notnull().any():
total_weights = weights.where(da.notnull()).sum(dim=dim)
else:
total_weights = weights.sum(dim)
return (da * weights).sum(dim, **kwargs) / total_weights # }}}
def _average_ds(ds, dim=None, weights=None, **kwargs): # {{{
"""
weighted average for Datasets
Parameters
----------
dim : str or sequence of str, optional
Dimension(s) over which to apply average.
weights : DataArray
weights to apply. Shape must be broadcastable to shape of data.
kwargs : dict
Additional keyword arguments passed on to internal calls to ``mean``
or ``sum`` (performed on the data set or data array but *not* those
performed on the weights)
Returns
-------
reduced : Dataset
New Dataset with average applied to its data and the indicated
dimension(s) removed.
Authors
-------
Mathias Hauser (https://github.com/mathause)
Xylar Asay-Davis
"""
if weights is None:
return ds.mean(dim, **kwargs)
else:
return ds.apply(_average_da, dim=dim, weights=weights, **kwargs) # }}}
# vim: foldmethod=marker ai ts=4 sts=4 et sw=4 ft=python