Skip to content

Commit 551a7bc

Browse files
authored
MultiIndex level coordinates as Dataset attributes (#1006)
Follow-up on GH947 This ensures that you can pull out MultiIndex levels via attribute style access on Dataset objects, as well as DataArray objects. CC benbovy
1 parent f40d323 commit 551a7bc

File tree

5 files changed

+15
-7
lines changed

5 files changed

+15
-7
lines changed

xarray/core/common.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ class AttrAccessMixin(object):
181181
@property
182182
def _attr_sources(self):
183183
"""List of places to look-up items for attribute-style access"""
184-
return [self, self.attrs]
184+
return []
185185

186186
def __getattr__(self, name):
187187
if name != '__setstate__':

xarray/core/coordinates.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,8 @@ def __delitem__(self, key):
215215
del self._data._coords[key]
216216

217217

218-
class DataArrayLevelCoordinates(AbstractCoordinates):
219-
"""Dictionary like container for DataArray MultiIndex level coordinates.
218+
class LevelCoordinates(AbstractCoordinates):
219+
"""Dictionary like container for MultiIndex level coordinates.
220220
221221
Used for attribute style lookup. Not returned directly by any
222222
public methods.
@@ -232,7 +232,7 @@ def _names(self):
232232
def variables(self):
233233
level_coords = OrderedDict(
234234
(k, self._data[v].variable.get_level_variable(k))
235-
for k, v in self._data._level_coords.items())
235+
for k, v in self._data._level_coords.items())
236236
return Frozen(level_coords)
237237

238238

xarray/core/dataarray.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
from . import utils
1515
from .alignment import align
1616
from .common import AbstractArray, BaseDataObject, squeeze
17-
from .coordinates import (DataArrayCoordinates, DataArrayLevelCoordinates,
17+
from .coordinates import (DataArrayCoordinates, LevelCoordinates,
1818
Indexes)
1919
from .dataset import Dataset
2020
from .pycompat import iteritems, basestring, OrderedDict, zip
@@ -467,7 +467,7 @@ def __delitem__(self, key):
467467
@property
468468
def _attr_sources(self):
469469
"""List of places to look-up items for attribute-style access"""
470-
return [self.coords, DataArrayLevelCoordinates(self), self.attrs]
470+
return [self.coords, LevelCoordinates(self), self.attrs]
471471

472472
def __contains__(self, key):
473473
return key in self._coords

xarray/core/dataset.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from . import formatting
1616
from .. import conventions
1717
from .alignment import align
18-
from .coordinates import DatasetCoordinates, Indexes
18+
from .coordinates import DatasetCoordinates, LevelCoordinates, Indexes
1919
from .common import ImplementsDatasetReduce, BaseDataObject
2020
from .merge import (dataset_update_method, dataset_merge_method,
2121
merge_data_and_coords)
@@ -487,6 +487,11 @@ def __deepcopy__(self, memo=None):
487487
# copy.deepcopy
488488
return self.copy(deep=True)
489489

490+
@property
491+
def _attr_sources(self):
492+
"""List of places to look-up items for attribute-style access"""
493+
return [self, LevelCoordinates(self), self.attrs]
494+
490495
def __contains__(self, key):
491496
"""The 'in' operator will return true or false depending on whether
492497
'key' is an array in the dataset or not.

xarray/test/test_dataset.py

+3
Original file line numberDiff line numberDiff line change
@@ -1540,6 +1540,9 @@ def test_virtual_variable_multiindex(self):
15401540
name='hour', coords=[mindex], dims='x')
15411541
self.assertDataArrayIdentical(expected, data['level_date.hour'])
15421542

1543+
# attribute style access
1544+
self.assertDataArrayIdentical(data.level_str, data['level_str'])
1545+
15431546
def test_time_season(self):
15441547
ds = Dataset({'t': pd.date_range('2000-01-01', periods=12, freq='M')})
15451548
expected = ['DJF'] * 2 + ['MAM'] * 3 + ['JJA'] * 3 + ['SON'] * 3 + ['DJF']

0 commit comments

Comments
 (0)