Skip to content

Commit 6d8971b

Browse files
authored
Merge pull request #28 from CMCC-Foundation/v0.2.7.9-hotfix
hotfix for resample function
2 parents 9fb584e + 41edec4 commit 6d8971b

File tree

2 files changed

+33
-86
lines changed

2 files changed

+33
-86
lines changed

geokube/core/field.py

Lines changed: 32 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,95 +1060,42 @@ def resample(
10601060
>>> resulting_field = field.resample("sum", frequency='2M')
10611061
10621062
"""
1063-
if callable(operator):
1064-
func = operator
1065-
else:
1066-
if isinstance(operator, str):
1067-
operator_func = MethodType(operator)
1068-
elif isinstance(operator, MethodType):
1069-
operator_func = operator
1070-
else:
1071-
raise TypeError(
1072-
"Operator must be `str`, `MethodType`, or `callable`."
1073-
" Provided `{type(operator)}`"
1074-
)
1075-
if operator_func is MethodType.UNDEFINED:
1076-
methods = {
1077-
method.value[0]
1078-
for method in MethodType.__members__.values()
1079-
}
1080-
methods.discard("<undefined>")
1081-
raise ValueError(
1082-
f"Provided operator '{operator}' was not found! Available"
1083-
f" operators are: {sorted(methods)}!"
1084-
)
1085-
func = (
1086-
operator_func.dask_operator
1087-
if is_dask_collection(self)
1088-
else operator_func.numpy_operator
1089-
)
1090-
1091-
# ################## Temporary solution for time bounds adjustmnent ######################
1092-
1093-
# TODO: handle `formula_terms` bounds attribute
1094-
# http://cfconventions.org/cf-conventions/cf-conventions.html#cell-boundaries
10951063
ds = self.to_xarray(encoding=False)
1096-
if (time_bnds := self.time.bounds) is None:
1097-
bnds_name, bnds = f"{self.time.name}_bnds", None
1098-
else:
1099-
((bnds_name, bnds),) = time_bnds.items()
1100-
if self.cell_methods and bnds is not None:
1101-
# `closed=right` set by default for {"M", "A", "Q", "BM", "BA", "BQ", "W"} resampling codes ("D" not included!)
1102-
# https://github.com/pandas-dev/pandas/blob/7c48ff4409c622c582c56a5702373f726de08e96/pandas/core/resample.py#L1383
1103-
resample_kwargs.update({"closed": "right"})
1104-
da = ds.resample(
1105-
indexer={self.time.name: frequency}, **resample_kwargs
1106-
)
1107-
new_bnds = np.empty(
1108-
shape=(len(da.groups), 2), dtype=np.dtype("datetime64[ns]")
1109-
)
1110-
for i, v in enumerate(da.groups.values()):
1111-
new_bnds[i] = [bnds.values[v].min(), bnds.values[v].max()]
1112-
# TODO: Check if this is redundant
1113-
if bnds is None:
1114-
Field._LOG.warn(
1115-
"Time bounds not defined for the cell methods!"
1116-
)
1117-
warnings.warn("Time bounds not defined for the cell methods!")
1064+
encodings = ds.encoding
1065+
if frequency == '1D':
1066+
match operator:
1067+
case "max":
1068+
ds = ds.coarsen(time=24).max()
1069+
case "min":
1070+
ds = ds.coarsen(time=24).min()
1071+
case "sum":
1072+
ds = ds.coarsen(time=24).sum()
1073+
case "mean":
1074+
ds = ds.coarsen(time=24).mean()
1075+
case "median":
1076+
ds = ds.coarsen(time=24).median()
1077+
case _:
1078+
raise NotImplementedError(f"Operator {operator} not implemented.")
11181079
else:
1119-
da = ds.resample(
1120-
indexer={self.time.name: frequency}, **resample_kwargs
1121-
)
1122-
new_bnds = np.empty(
1123-
shape=(len(da.groups), 2), dtype=np.dtype("datetime64[ns]")
1124-
)
1125-
for i, v in enumerate(da.groups.values()):
1126-
new_bnds[i] = [
1127-
self.time.values[v].min(),
1128-
self.time.values[v].max(),
1129-
]
1130-
1131-
# NOTE: `reduce` spans result for all intermediate values
1132-
# if 1st and 3rd day os selected and 1D freq is used
1133-
# then `reduce` results in time axis for 1st, 2nd, and 3rd
1134-
# passing for missing dates `NaN`s
1135-
da = da.reduce(func=func, dim=self.time.name, keep_attrs=True).dropna(
1136-
dim=self.time.name, how="all"
1137-
)
1138-
# NOTE: `reduce` removes all `encoding` properties
1139-
da[self.name].encoding = ds[self.name].encoding
1140-
res = xr.Dataset(
1141-
da,
1142-
coords={f"{bnds_name}": ((self.time.name, "bnds"), new_bnds)},
1143-
)
1144-
field = Field.from_xarray(res, ncvar=self.name)
1145-
field.time.bounds = new_bnds
1080+
ds = ds.resample(time=frequency)
1081+
match operator:
1082+
case "max":
1083+
ds = ds.max(dim="time")
1084+
case "min":
1085+
ds = ds.min(dim="time")
1086+
case "sum":
1087+
ds = ds.sum(dim="time")
1088+
case "mean":
1089+
ds = ds.mean(dim="time")
1090+
case "median":
1091+
ds = ds.median(dim="time")
1092+
case _:
1093+
raise NotImplementedError(f"Operator {operator} not implemented.")
1094+
ds.encoding = encodings
1095+
field = Field.from_xarray(ds, ncvar=self.name)
11461096
field.domain.crs = self.domain.crs
11471097
field.domain._type = self.domain._type
1148-
1149-
# TODO: adjust cell_methods after resampling!
1150-
1151-
# #########################################################################################
1098+
field.domain._calculate_missing_lat_and_lon()
11521099
return field
11531100

11541101
@geokube_logging

geokube/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.2.7.9"
1+
__version__ = "0.2.7.10"

0 commit comments

Comments
 (0)