21
21
from .coordinates import (DatasetCoordinates , LevelCoordinatesSource ,
22
22
assert_coordinate_consistent , remap_label_indexers )
23
23
from .duck_array_ops import datetime_to_numeric
24
- from .indexes import Indexes , default_indexes , isel_variable_and_index
25
- from .merge import (dataset_merge_method , dataset_update_method ,
26
- merge_data_and_coords , merge_variables )
24
+ from .indexes import (
25
+ Indexes , default_indexes , isel_variable_and_index , roll_index ,
26
+ )
27
+ from .merge import (
28
+ dataset_merge_method , dataset_update_method , merge_data_and_coords ,
29
+ merge_variables )
27
30
from .options import OPTIONS , _get_keep_attrs
28
31
from .pycompat import TYPE_CHECKING , dask_array_type
29
32
from .utils import (Frozen , SortedKeysDict , _check_inplace ,
@@ -2693,17 +2696,18 @@ def reorder_levels(self, dim_order=None, inplace=None,
2693
2696
inplace = _check_inplace (inplace )
2694
2697
dim_order = either_dict_or_kwargs (dim_order , dim_order_kwargs ,
2695
2698
'reorder_levels' )
2696
- replace_variables = {}
2699
+ variables = self ._variables .copy ()
2700
+ indexes = OrderedDict (self .indexes )
2697
2701
for dim , order in dim_order .items ():
2698
2702
coord = self ._variables [dim ]
2699
- index = coord . to_index ()
2703
+ index = self . indexes [ dim ]
2700
2704
if not isinstance (index , pd .MultiIndex ):
2701
2705
raise ValueError ("coordinate %r has no MultiIndex" % dim )
2702
- replace_variables [ dim ] = IndexVariable ( coord . dims ,
2703
- index . reorder_levels ( order ) )
2704
- variables = self . _variables . copy ()
2705
- variables . update ( replace_variables )
2706
- return self ._replace_vars_and_dims (variables , inplace = inplace )
2706
+ new_index = index . reorder_levels ( order )
2707
+ variables [ dim ] = IndexVariable ( coord . dims , new_index )
2708
+ indexes [ dim ] = new_index
2709
+
2710
+ return self ._replace (variables , indexes = indexes , inplace = inplace )
2707
2711
2708
2712
def _stack_once (self , dims , new_dim ):
2709
2713
variables = OrderedDict ()
@@ -2733,7 +2737,12 @@ def _stack_once(self, dims, new_dim):
2733
2737
2734
2738
coord_names = set (self ._coord_names ) - set (dims ) | set ([new_dim ])
2735
2739
2736
- return self ._replace_vars_and_dims (variables , coord_names )
2740
+ indexes = OrderedDict ((k , v ) for k , v in self .indexes .items ()
2741
+ if k not in dims )
2742
+ indexes [new_dim ] = idx
2743
+
2744
+ return self ._replace_with_new_dims (
2745
+ variables , coord_names = coord_names , indexes = indexes )
2737
2746
2738
2747
def stack (self , dimensions = None , ** dimensions_kwargs ):
2739
2748
"""
@@ -2900,6 +2909,9 @@ def _unstack_once(self, dim):
2900
2909
new_dim_sizes = [lev .size for lev in index .levels ]
2901
2910
2902
2911
variables = OrderedDict ()
2912
+ indexes = OrderedDict (
2913
+ (k , v ) for k , v in self .indexes .items () if k != dim )
2914
+
2903
2915
for name , var in obj .variables .items ():
2904
2916
if name != dim :
2905
2917
if dim in var .dims :
@@ -2910,10 +2922,12 @@ def _unstack_once(self, dim):
2910
2922
2911
2923
for name , lev in zip (new_dim_names , index .levels ):
2912
2924
variables [name ] = IndexVariable (name , lev )
2925
+ indexes [name ] = lev
2913
2926
2914
2927
coord_names = set (self ._coord_names ) - set ([dim ]) | set (new_dim_names )
2915
2928
2916
- return self ._replace_vars_and_dims (variables , coord_names )
2929
+ return self ._replace_with_new_dims (
2930
+ variables , coord_names = coord_names , indexes = indexes )
2917
2931
2918
2932
def unstack (self , dim = None ):
2919
2933
"""
@@ -3098,7 +3112,10 @@ def _drop_vars(self, names, errors='raise'):
3098
3112
variables = OrderedDict ((k , v ) for k , v in self ._variables .items ()
3099
3113
if k not in drop )
3100
3114
coord_names = set (k for k in self ._coord_names if k in variables )
3101
- return self ._replace_vars_and_dims (variables , coord_names )
3115
+ indexes = OrderedDict ((k , v ) for k , v in self .indexes .items ()
3116
+ if k not in drop )
3117
+ return self ._replace_with_new_dims (
3118
+ variables , coord_names = coord_names , indexes = indexes )
3102
3119
3103
3120
def drop_dims (self , drop_dims , * , errors = 'raise' ):
3104
3121
"""Drop dimensions and associated variables from this dataset.
@@ -3133,12 +3150,7 @@ def drop_dims(self, drop_dims, *, errors='raise'):
3133
3150
3134
3151
drop_vars = set (k for k , v in self ._variables .items ()
3135
3152
for d in v .dims if d in drop_dims )
3136
-
3137
- variables = OrderedDict ((k , v ) for k , v in self ._variables .items ()
3138
- if k not in drop_vars )
3139
- coord_names = set (k for k in self ._coord_names if k in variables )
3140
-
3141
- return self ._replace_with_new_dims (variables , coord_names )
3153
+ return self ._drop_vars (drop_vars )
3142
3154
3143
3155
def transpose (self , * dims ):
3144
3156
"""Return a new Dataset object with all array dimensions transposed.
@@ -3457,8 +3469,11 @@ def reduce(self, func, dim=None, keep_attrs=None, keepdims=False,
3457
3469
** kwargs )
3458
3470
3459
3471
coord_names = set (k for k in self .coords if k in variables )
3472
+ indexes = OrderedDict ((k , v ) for k , v in self .indexes .items ()
3473
+ if k in variables )
3460
3474
attrs = self .attrs if keep_attrs else None
3461
- return self ._replace_vars_and_dims (variables , coord_names , attrs = attrs )
3475
+ return self ._replace_with_new_dims (
3476
+ variables , coord_names = coord_names , attrs = attrs , indexes = indexes )
3462
3477
3463
3478
def apply (self , func , keep_attrs = None , args = (), ** kwargs ):
3464
3479
"""Apply a function over the data variables in this dataset.
@@ -3854,8 +3869,9 @@ def func(self, other):
3854
3869
other = other .reindex_like (self , copy = False )
3855
3870
g = ops .inplace_to_noninplace_op (f )
3856
3871
ds = self ._calculate_binary_op (g , other , inplace = True )
3857
- self ._replace_vars_and_dims (ds ._variables , ds ._coord_names ,
3858
- attrs = ds ._attrs , inplace = True )
3872
+ self ._replace_with_new_dims (ds ._variables , ds ._coord_names ,
3873
+ attrs = ds ._attrs , indexes = ds ._indexes ,
3874
+ inplace = True )
3859
3875
return self
3860
3876
3861
3877
return func
@@ -3980,7 +3996,11 @@ def diff(self, dim, n=1, label='upper'):
3980
3996
else :
3981
3997
variables [name ] = var
3982
3998
3983
- difference = self ._replace_vars_and_dims (variables )
3999
+ indexes = OrderedDict (self .indexes )
4000
+ if dim in indexes :
4001
+ indexes [dim ] = indexes [dim ][kwargs_new [dim ]]
4002
+
4003
+ difference = self ._replace_with_new_dims (variables , indexes = indexes )
3984
4004
3985
4005
if n > 1 :
3986
4006
return difference .diff (dim , n - 1 )
@@ -4042,7 +4062,7 @@ def shift(self, shifts=None, fill_value=dtypes.NA, **shifts_kwargs):
4042
4062
else :
4043
4063
variables [name ] = var
4044
4064
4045
- return self ._replace_vars_and_dims (variables )
4065
+ return self ._replace (variables )
4046
4066
4047
4067
def roll (self , shifts = None , roll_coords = None , ** shifts_kwargs ):
4048
4068
"""Roll this dataset by an offset along one or more dimensions.
@@ -4109,7 +4129,16 @@ def roll(self, shifts=None, roll_coords=None, **shifts_kwargs):
4109
4129
else :
4110
4130
variables [k ] = v
4111
4131
4112
- return self ._replace_vars_and_dims (variables )
4132
+ if roll_coords :
4133
+ indexes = OrderedDict ()
4134
+ for k , v in self .indexes .items ():
4135
+ (dim ,) = self .variables [k ].dims
4136
+ if dim in shifts :
4137
+ indexes [k ] = roll_index (v , shifts [dim ])
4138
+ else :
4139
+ indexes = OrderedDict (self .indexes )
4140
+
4141
+ return self ._replace (variables , indexes = indexes )
4113
4142
4114
4143
def sortby (self , variables , ascending = True ):
4115
4144
"""
@@ -4251,10 +4280,14 @@ def quantile(self, q, dim=None, interpolation='linear',
4251
4280
4252
4281
# construct the new dataset
4253
4282
coord_names = set (k for k in self .coords if k in variables )
4283
+ indexes = OrderedDict (
4284
+ (k , v ) for k , v in self .indexes .items () if k in variables
4285
+ )
4254
4286
if keep_attrs is None :
4255
4287
keep_attrs = _get_keep_attrs (default = False )
4256
4288
attrs = self .attrs if keep_attrs else None
4257
- new = self ._replace_vars_and_dims (variables , coord_names , attrs = attrs )
4289
+ new = self ._replace_with_new_dims (
4290
+ variables , coord_names = coord_names , attrs = attrs , indexes = indexes )
4258
4291
if 'quantile' in new .dims :
4259
4292
new .coords ['quantile' ] = Variable ('quantile' , q )
4260
4293
else :
@@ -4305,7 +4338,7 @@ def rank(self, dim, pct=False, keep_attrs=None):
4305
4338
if keep_attrs is None :
4306
4339
keep_attrs = _get_keep_attrs (default = False )
4307
4340
attrs = self .attrs if keep_attrs else None
4308
- return self ._replace_vars_and_dims (variables , coord_names , attrs = attrs )
4341
+ return self ._replace (variables , coord_names , attrs = attrs )
4309
4342
4310
4343
def differentiate (self , coord , edge_order = 1 , datetime_unit = None ):
4311
4344
""" Differentiate with the second order accurate central
@@ -4363,7 +4396,7 @@ def differentiate(self, coord, edge_order=1, datetime_unit=None):
4363
4396
variables [k ] = Variable (v .dims , grad )
4364
4397
else :
4365
4398
variables [k ] = v
4366
- return self ._replace_vars_and_dims (variables )
4399
+ return self ._replace (variables )
4367
4400
4368
4401
def integrate (self , coord , datetime_unit = None ):
4369
4402
""" integrate the array with the trapezoidal rule.
@@ -4435,7 +4468,11 @@ def _integrate_one(self, coord, datetime_unit=None):
4435
4468
variables [k ] = Variable (v_dims , integ )
4436
4469
else :
4437
4470
variables [k ] = v
4438
- return self ._replace_vars_and_dims (variables , coord_names = coord_names )
4471
+ indexes = OrderedDict (
4472
+ (k , v ) for k , v in self .indexes .items () if k in variables
4473
+ )
4474
+ return self ._replace_with_new_dims (
4475
+ variables , coord_names = coord_names , indexes = indexes )
4439
4476
4440
4477
@property
4441
4478
def real (self ):
0 commit comments