77from . import dtypes , duck_array_ops , utils
88from .dask_array_ops import dask_rolling_wrapper
99from .ops import inject_reduce_methods
10+ from .options import _get_keep_attrs
1011from .pycompat import dask_array_type
1112
1213try :
@@ -42,10 +43,10 @@ class Rolling:
4243 DataArray.rolling
4344 """
4445
45- __slots__ = ("obj" , "window" , "min_periods" , "center" , "dim" )
46- _attributes = ("window" , "min_periods" , "center" , "dim" )
46+ __slots__ = ("obj" , "window" , "min_periods" , "center" , "dim" , "keep_attrs" )
47+ _attributes = ("window" , "min_periods" , "center" , "dim" , "keep_attrs" )
4748
48- def __init__ (self , obj , windows , min_periods = None , center = False ):
49+ def __init__ (self , obj , windows , min_periods = None , center = False , keep_attrs = None ):
4950 """
5051 Moving window object.
5152
@@ -65,6 +66,10 @@ def __init__(self, obj, windows, min_periods=None, center=False):
6566 setting min_periods equal to the size of the window.
6667 center : boolean, default False
6768 Set the labels at the center of the window.
69+ keep_attrs : bool, optional
70+ If True, the object's attributes (`attrs`) will be copied from
71+ the original object to the new one. If False (default), the new
72+ object will be returned without attributes.
6873
6974 Returns
7075 -------
@@ -89,6 +94,10 @@ def __init__(self, obj, windows, min_periods=None, center=False):
8994 self .center = center
9095 self .dim = dim
9196
97+ if keep_attrs is None :
98+ keep_attrs = _get_keep_attrs (default = False )
99+ self .keep_attrs = keep_attrs
100+
92101 @property
93102 def _min_periods (self ):
94103 return self .min_periods if self .min_periods is not None else self .window
@@ -143,7 +152,7 @@ def count(self):
143152class DataArrayRolling (Rolling ):
144153 __slots__ = ("window_labels" ,)
145154
146- def __init__ (self , obj , windows , min_periods = None , center = False ):
155+ def __init__ (self , obj , windows , min_periods = None , center = False , keep_attrs = None ):
147156 """
148157 Moving window object for DataArray.
149158 You should use DataArray.rolling() method to construct this object
@@ -165,6 +174,10 @@ def __init__(self, obj, windows, min_periods=None, center=False):
165174 setting min_periods equal to the size of the window.
166175 center : boolean, default False
167176 Set the labels at the center of the window.
177+ keep_attrs : bool, optional
178+ If True, the object's attributes (`attrs`) will be copied from
179+ the original object to the new one. If False (default), the new
180+ object will be returned without attributes.
168181
169182 Returns
170183 -------
@@ -177,7 +190,11 @@ def __init__(self, obj, windows, min_periods=None, center=False):
177190 Dataset.rolling
178191 Dataset.groupby
179192 """
180- super ().__init__ (obj , windows , min_periods = min_periods , center = center )
193+ if keep_attrs is None :
194+ keep_attrs = _get_keep_attrs (default = False )
195+ super ().__init__ (
196+ obj , windows , min_periods = min_periods , center = center , keep_attrs = keep_attrs
197+ )
181198
182199 self .window_labels = self .obj [self .dim ]
183200
@@ -374,7 +391,7 @@ def _numpy_or_bottleneck_reduce(
374391class DatasetRolling (Rolling ):
375392 __slots__ = ("rollings" ,)
376393
377- def __init__ (self , obj , windows , min_periods = None , center = False ):
394+ def __init__ (self , obj , windows , min_periods = None , center = False , keep_attrs = None ):
378395 """
379396 Moving window object for Dataset.
380397 You should use Dataset.rolling() method to construct this object
@@ -396,6 +413,10 @@ def __init__(self, obj, windows, min_periods=None, center=False):
396413 setting min_periods equal to the size of the window.
397414 center : boolean, default False
398415 Set the labels at the center of the window.
416+ keep_attrs : bool, optional
417+ If True, the object's attributes (`attrs`) will be copied from
418+ the original object to the new one. If False (default), the new
419+ object will be returned without attributes.
399420
400421 Returns
401422 -------
@@ -408,15 +429,17 @@ def __init__(self, obj, windows, min_periods=None, center=False):
408429 Dataset.groupby
409430 DataArray.groupby
410431 """
411- super ().__init__ (obj , windows , min_periods , center )
432+ super ().__init__ (obj , windows , min_periods , center , keep_attrs )
412433 if self .dim not in self .obj .dims :
413434 raise KeyError (self .dim )
414435 # Keep each Rolling object as a dictionary
415436 self .rollings = {}
416437 for key , da in self .obj .data_vars .items ():
417438 # keeps rollings only for the dataset depending on slf.dim
418439 if self .dim in da .dims :
419- self .rollings [key ] = DataArrayRolling (da , windows , min_periods , center )
440+ self .rollings [key ] = DataArrayRolling (
441+ da , windows , min_periods , center , keep_attrs
442+ )
420443
421444 def _dataset_implementation (self , func , ** kwargs ):
422445 from .dataset import Dataset
@@ -427,7 +450,8 @@ def _dataset_implementation(self, func, **kwargs):
427450 reduced [key ] = func (self .rollings [key ], ** kwargs )
428451 else :
429452 reduced [key ] = self .obj [key ]
430- return Dataset (reduced , coords = self .obj .coords )
453+ attrs = self .obj .attrs if self .keep_attrs else {}
454+ return Dataset (reduced , coords = self .obj .coords , attrs = attrs )
431455
432456 def reduce (self , func , ** kwargs ):
433457 """Reduce the items in this group by applying `func` along some
@@ -466,7 +490,7 @@ def _numpy_or_bottleneck_reduce(
466490 ** kwargs ,
467491 )
468492
469- def construct (self , window_dim , stride = 1 , fill_value = dtypes .NA ):
493+ def construct (self , window_dim , stride = 1 , fill_value = dtypes .NA , keep_attrs = None ):
470494 """
471495 Convert this rolling object to xr.Dataset,
472496 where the window dimension is stacked as a new dimension
@@ -487,6 +511,9 @@ def construct(self, window_dim, stride=1, fill_value=dtypes.NA):
487511
488512 from .dataset import Dataset
489513
514+ if keep_attrs is None :
515+ keep_attrs = _get_keep_attrs (default = True )
516+
490517 dataset = {}
491518 for key , da in self .obj .data_vars .items ():
492519 if self .dim in da .dims :
@@ -509,10 +536,18 @@ class Coarsen:
509536 DataArray.coarsen
510537 """
511538
512- __slots__ = ("obj" , "boundary" , "coord_func" , "windows" , "side" , "trim_excess" )
539+ __slots__ = (
540+ "obj" ,
541+ "boundary" ,
542+ "coord_func" ,
543+ "windows" ,
544+ "side" ,
545+ "trim_excess" ,
546+ "keep_attrs" ,
547+ )
513548 _attributes = ("windows" , "side" , "trim_excess" )
514549
515- def __init__ (self , obj , windows , boundary , side , coord_func ):
550+ def __init__ (self , obj , windows , boundary , side , coord_func , keep_attrs ):
516551 """
517552 Moving window object.
518553
@@ -541,6 +576,7 @@ def __init__(self, obj, windows, boundary, side, coord_func):
541576 self .windows = windows
542577 self .side = side
543578 self .boundary = boundary
579+ self .keep_attrs = keep_attrs
544580
545581 absent_dims = [dim for dim in windows .keys () if dim not in self .obj .dims ]
546582 if absent_dims :
@@ -626,6 +662,11 @@ def _reduce_method(cls, func: Callable, include_skipna: bool, numeric_only: bool
626662 def wrapped_func (self , ** kwargs ):
627663 from .dataset import Dataset
628664
665+ if self .keep_attrs :
666+ attrs = self .obj .attrs
667+ else :
668+ attrs = {}
669+
629670 reduced = {}
630671 for key , da in self .obj .data_vars .items ():
631672 reduced [key ] = da .variable .coarsen (
@@ -644,7 +685,7 @@ def wrapped_func(self, **kwargs):
644685 )
645686 else :
646687 coords [c ] = v .variable
647- return Dataset (reduced , coords = coords )
688+ return Dataset (reduced , coords = coords , attrs = attrs )
648689
649690 return wrapped_func
650691
0 commit comments