-
Notifications
You must be signed in to change notification settings - Fork 284
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Partial collapse of multi-dimensional coordinates #3028
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
* The partial collapse of multi-dimensional auxiliary coordinates is now | ||
supported. Collapsed bounds span the range of the collapsed dimension(s). |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1169,20 +1169,14 @@ def collapsed(self, dims_to_collapse=None): | |
the specified dimensions. | ||
|
||
Replaces the points & bounds with a simple bounded region. | ||
|
||
.. note:: | ||
You cannot partially collapse a multi-dimensional coordinate. See | ||
:ref:`cube.collapsed <partially_collapse_multi-dim_coord>` for more | ||
information. | ||
|
||
""" | ||
import dask.array as da | ||
# Ensure dims_to_collapse is a tuple to be able to pass | ||
# through to numpy | ||
if isinstance(dims_to_collapse, (int, np.integer)): | ||
dims_to_collapse = [dims_to_collapse] | ||
|
||
if dims_to_collapse is not None and \ | ||
set(range(self.ndim)) != set(dims_to_collapse): | ||
raise ValueError('Cannot partially collapse a coordinate (%s).' | ||
% self.name()) | ||
dims_to_collapse = (dims_to_collapse, ) | ||
if isinstance(dims_to_collapse, list): | ||
dims_to_collapse = tuple(dims_to_collapse) | ||
|
||
if np.issubdtype(self.dtype, np.str_): | ||
# Collapse the coordinate by serializing the points and | ||
|
@@ -1215,28 +1209,20 @@ def serialize(x): | |
'Metadata may not be fully descriptive for {!r}.' | ||
warnings.warn(msg.format(self.name())) | ||
|
||
# Create bounds for the new collapsed coordinate. | ||
item = self.core_bounds() if self.has_bounds() \ | ||
# Determine the array library for stacking | ||
al = da if self.has_bounds() \ | ||
and _lazy.is_lazy_data(self.core_bounds()) else np | ||
|
||
item = al.concatenate(self.core_bounds()) if self.has_bounds() \ | ||
else self.core_points() | ||
lower, upper = item.min(), item.max() | ||
bounds_dtype = item.dtype | ||
# Ensure 2D shape of new bounds. | ||
bounds = np.empty((1, 2), 'object') | ||
bounds[0, 0] = lower | ||
bounds[0, 1] = upper | ||
# Create points for the new collapsed coordinate. | ||
points_dtype = self.dtype | ||
points = (float(lower) + float(upper)) * 0.5 | ||
|
||
# Calculate the bounds and points along the right dims | ||
bounds = al.stack([item.min(axis=dims_to_collapse), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if dims to collapse are negative and item is bounds (which has an extra trailing dimension)? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we ever want to produce more than 2 bounds? For instance, when collapsing a There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested negative dims_to_collapse with:
Both the following hold true:
|
||
item.max(axis=dims_to_collapse)]).T | ||
points = al.array(bounds.sum(axis=-1) * 0.5, dtype=self.dtype) | ||
|
||
# Create the new collapsed coordinate. | ||
if _lazy.is_lazy_data(item): | ||
bounds = _lazy.multidim_lazy_stack(bounds) | ||
coord = self.copy(points=points, bounds=bounds) | ||
else: | ||
bounds = np.concatenate(bounds) | ||
bounds = np.array(bounds, dtype=bounds_dtype) | ||
coord = self.copy(points=np.array(points, dtype=points_dtype), | ||
bounds=bounds) | ||
coord = self.copy(points=points, bounds=bounds) | ||
return coord | ||
|
||
def _guess_bounds(self, bound_position=0.5): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a warning above:
I guess that triggers when we completely collapse a multi-dim coord (rather than partially).
Nothing to do here, just reminding myself of the code! 😄