Skip to content

Commit

Permalink
rewritten checking uniqueness of multi-index level names
Browse files Browse the repository at this point in the history
  • Loading branch information
Benoit Bovy committed Aug 31, 2016
1 parent c03dfa4 commit 4672448
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 27 deletions.
12 changes: 3 additions & 9 deletions xarray/core/dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
from .dataset import Dataset
from .pycompat import iteritems, basestring, OrderedDict, zip
from .variable import (as_variable, Variable, as_compatible_data, Coordinate,
default_index_coordinate)
default_index_coordinate,
assert_unique_multiindex_level_names)
from .formatting import format_item


Expand Down Expand Up @@ -81,14 +82,7 @@ def _infer_coords_and_dims(shape, coords, dims):
'length %s on the data but length %s on '
'coordinate %r' % (d, sizes[d], s, k))

if v.ndim == 1:
idx_level_names = v.to_coord().level_names or []
for n in idx_level_names:
if n in level_names:
raise ValueError('found duplicate MultiIndex level '
'name %r for coordinates %r and %r'
% (n, k, level_names[n]))
level_names[n] = k
assert_unique_multiindex_level_names(new_coords)

return new_coords, dims

Expand Down
16 changes: 0 additions & 16 deletions xarray/core/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,6 @@ def __init__(self, data_vars=None, coords=None, attrs=None,
coords = {}
if data_vars is not None or coords is not None:
self._set_init_vars_and_dims(data_vars, coords, compat)
self._check_multiindex_level_names()
if attrs is not None:
self.attrs = attrs
self._initialized = True
Expand All @@ -251,21 +250,6 @@ def _set_init_vars_and_dims(self, data_vars, coords, compat):
self._coord_names = coord_names
self._dims = dims

def _check_multiindex_level_names(self):
"""Check for uniqueness of MultiIndex level names
"""
level_names = {}
for c in self._coord_names:
v = self._variables[c]
if v.ndim == 1 and v._in_memory:
idx_level_names = v.to_coord().level_names or []
for n in idx_level_names:
if n in level_names:
raise ValueError('found duplicate MultiIndex level '
'name %r for coordinates %r and %r'
% (n, c, level_names[n]))
level_names[n] = c

@classmethod
def load_store(cls, store, decoder=None):
"""Create a new dataset from the contents of a backends.*DataStore
Expand Down
8 changes: 6 additions & 2 deletions xarray/core/merge.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

from .alignment import deep_align
from .utils import Frozen
from .variable import as_variable, default_index_coordinate
from .variable import (as_variable, default_index_coordinate,
assert_unique_multiindex_level_names)
from .pycompat import (basestring, OrderedDict)


Expand Down Expand Up @@ -110,7 +111,7 @@ def merge_variables(
If provided, variables are always taken from this dict in preference to
the input variable dictionaries, without checking for conflicts.
compat : {'identical', 'equals', 'broadcast_equals', 'minimal'}, optional
Type of equality check to use wben checking for conflicts.
Type of equality check to use when checking for conflicts.
Returns
-------
Expand Down Expand Up @@ -278,6 +279,7 @@ def merge_coords_only(objs, priority_vars=None):
"""
expanded = expand_variable_dicts(objs)
variables = merge_variables(expanded, priority_vars)
assert_unique_multiindex_level_names(variables)
return variables


Expand Down Expand Up @@ -319,6 +321,7 @@ def align_and_merge_coords(objs, compat='minimal', join='outer',
expanded = expand_variable_dicts(aligned)
priority_vars = _get_priority_vars(aligned, priority_arg, compat=compat)
variables = merge_variables(expanded, priority_vars, compat=compat)
assert_unique_multiindex_level_names(variables)

return variables

Expand Down Expand Up @@ -380,6 +383,7 @@ def merge_core(objs, compat='broadcast_equals', join='outer', priority_arg=None,

priority_vars = _get_priority_vars(aligned, priority_arg, compat=compat)
variables = merge_variables(expanded, priority_vars, compat=compat)
assert_unique_multiindex_level_names(variables)

dims = calculate_dimensions(variables)

Expand Down
26 changes: 26 additions & 0 deletions xarray/core/variable.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from datetime import timedelta
from collections import defaultdict
import functools
import itertools
import warnings
Expand Down Expand Up @@ -1297,3 +1298,28 @@ def concat(variables, dim='concat_dim', positions=None, shortcut=False):
return Coordinate.concat(variables, dim, positions, shortcut)
else:
return Variable.concat(variables, dim, positions, shortcut)


def assert_unique_multiindex_level_names(variables):
"""Check for uniqueness of MultiIndex level names in all given
variables.
Not public API. Used for checking consistency of DataArray and Dataset
objects.
"""
level_names = defaultdict(list)
for var_name, var in variables.items():
if isinstance(var._data, PandasIndexAdapter):
idx_level_names = var.to_coord().level_names
if idx_level_names is not None:
for n in idx_level_names:
level_names[n].append(var_name)

duplicate_level_names = {k: v for k, v in level_names.items()
if len(v) > 1}
if duplicate_level_names:
duplicate_str = '\n'.join(['level %r found in %s'
% (k, ' and '.join(v))
for k, v in duplicate_level_names.items()])
raise ValueError('conflicting MultiIndex level names:\n%s'
% duplicate_str)

0 comments on commit 4672448

Please sign in to comment.