Skip to content

Commit 5fed753

Browse files
authored
Merge pull request #742 from davidhassell/collapse-speed
Improve `cf.Field.collapse` performance by lazily computing reduced axis coordinates
2 parents a90a26f + 2b89520 commit 5fed753

File tree

2 files changed

+32
-11
lines changed

2 files changed

+32
-11
lines changed

Changelog.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ version NEXT
99
to regrid the vertical axis in logarithmic coordinates to
1010
`cf.Field.regrids` and `cf.Field.regridc`
1111
(https://github.com/NCAS-CMS/cf-python/issues/715)
12+
* Improve `cf.Field.collapse` performance by lazily computing reduced
13+
axis coordinates (https://github.com/NCAS-CMS/cf-python/issues/741)
1214
* Fix misleading error message when it is not possible to create area
1315
weights requested from `cf.Field.collapse`
1416
(https://github.com/NCAS-CMS/cf-python/issues/731)

cf/field.py

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7149,14 +7149,37 @@ def collapse(
71497149
if dim is None:
71507150
continue
71517151

7152-
# Create a new dimension coordinate for this axis
7152+
# Create new dimension coordinate bounds
71537153
if dim.has_bounds():
7154-
bounds_data = [dim.bounds.datum(0), dim.bounds.datum(-1)]
7154+
b = dim.bounds.data
71557155
else:
7156-
bounds_data = [dim.datum(0), dim.datum(-1)]
7156+
b = dim.data
71577157

7158-
units = dim.Units
7158+
cached_elements = b._get_cached_elements()
7159+
try:
7160+
# Try to set the new bounds from cached values
7161+
bounds_data = Data(
7162+
[[cached_elements[0], cached_elements[-1]]],
7163+
dtype=b.dtype,
7164+
units=b.Units,
7165+
)
7166+
except KeyError:
7167+
# Otherwise create the new bounds lazily
7168+
ndim = b.ndim
7169+
bounds_data = Data.concatenate(
7170+
[
7171+
b[(slice(0, 1, 1),) * ndim],
7172+
b[(slice(-1, None, 1),) * ndim],
7173+
],
7174+
axis=-1,
7175+
copy=False,
7176+
)
7177+
if ndim == 1:
7178+
bounds_data.insert_dimension(0, inplace=True)
71597179

7180+
bounds = self._Bounds(data=bounds_data)
7181+
7182+
# Create a new dimension coordinate value
71607183
if coordinate == "min":
71617184
coordinate = "minimum"
71627185
print(
@@ -7171,21 +7194,17 @@ def collapse(
71717194
)
71727195

71737196
if coordinate == "mid_range":
7174-
data = Data(
7175-
[(bounds_data[0] + bounds_data[1]) * 0.5], units=units
7176-
)
7197+
data = bounds_data.mean(axes=1, weights=None, squeeze=True)
71777198
elif coordinate == "minimum":
7178-
data = dim.data.min()
7199+
data = dim.data.min(squeeze=False)
71797200
elif coordinate == "maximum":
7180-
data = dim.data.max()
7201+
data = dim.data.max(squeeze=False)
71817202
else:
71827203
raise ValueError(
71837204
"Can't collapse: Bad parameter value: "
71847205
f"coordinate={coordinate!r}"
71857206
)
71867207

7187-
bounds = self._Bounds(data=Data([bounds_data], units=units))
7188-
71897208
dim.set_data(data, copy=False)
71907209
dim.set_bounds(bounds, copy=False)
71917210

0 commit comments

Comments
 (0)