@@ -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
0 commit comments