Skip to content

Commit 9dc2c16

Browse files
author
Benoit Bovy
committed
rewritten checking uniqueness of multi-index level names
1 parent 4b8cf06 commit 9dc2c16

File tree

4 files changed

+35
-27
lines changed

4 files changed

+35
-27
lines changed

xarray/core/dataarray.py

+3-9
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919
from .dataset import Dataset
2020
from .pycompat import iteritems, basestring, OrderedDict, zip
2121
from .variable import (as_variable, Variable, as_compatible_data, Coordinate,
22-
default_index_coordinate)
22+
default_index_coordinate,
23+
assert_unique_multiindex_level_names)
2324
from .formatting import format_item
2425

2526

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

84-
if v.ndim == 1:
85-
idx_level_names = v.to_coord().level_names or []
86-
for n in idx_level_names:
87-
if n in level_names:
88-
raise ValueError('found duplicate MultiIndex level '
89-
'name %r for coordinates %r and %r'
90-
% (n, k, level_names[n]))
91-
level_names[n] = k
85+
assert_unique_multiindex_level_names(new_coords)
9286

9387
return new_coords, dims
9488

xarray/core/dataset.py

-16
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,6 @@ def __init__(self, data_vars=None, coords=None, attrs=None,
224224
coords = {}
225225
if data_vars is not None or coords is not None:
226226
self._set_init_vars_and_dims(data_vars, coords, compat)
227-
self._check_multiindex_level_names()
228227
if attrs is not None:
229228
self.attrs = attrs
230229
self._initialized = True
@@ -251,21 +250,6 @@ def _set_init_vars_and_dims(self, data_vars, coords, compat):
251250
self._coord_names = coord_names
252251
self._dims = dims
253252

254-
def _check_multiindex_level_names(self):
255-
"""Check for uniqueness of MultiIndex level names
256-
"""
257-
level_names = {}
258-
for c in self._coord_names:
259-
v = self._variables[c]
260-
if v.ndim == 1 and v._in_memory:
261-
idx_level_names = v.to_coord().level_names or []
262-
for n in idx_level_names:
263-
if n in level_names:
264-
raise ValueError('found duplicate MultiIndex level '
265-
'name %r for coordinates %r and %r'
266-
% (n, c, level_names[n]))
267-
level_names[n] = c
268-
269253
@classmethod
270254
def load_store(cls, store, decoder=None):
271255
"""Create a new dataset from the contents of a backends.*DataStore

xarray/core/merge.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
from .alignment import align
44
from .utils import Frozen, is_dict_like
5-
from .variable import as_variable, default_index_coordinate
5+
from .variable import (as_variable, default_index_coordinate,
6+
assert_unique_multiindex_level_names)
67
from .pycompat import (basestring, OrderedDict)
78

89

@@ -110,7 +111,7 @@ def merge_variables(
110111
If provided, variables are always taken from this dict in preference to
111112
the input variable dictionaries, without checking for conflicts.
112113
compat : {'identical', 'equals', 'broadcast_equals', 'minimal'}, optional
113-
Type of equality check to use wben checking for conflicts.
114+
Type of equality check to use when checking for conflicts.
114115
115116
Returns
116117
-------
@@ -278,6 +279,7 @@ def merge_coords_without_align(objs, priority_vars=None):
278279
"""
279280
expanded = expand_variable_dicts(objs)
280281
variables = merge_variables(expanded, priority_vars)
282+
assert_unique_multiindex_level_names(variables)
281283
return variables
282284

283285

@@ -370,6 +372,7 @@ def merge_coords(objs, compat='minimal', join='outer', priority_arg=None,
370372
expanded = expand_variable_dicts(aligned)
371373
priority_vars = _get_priority_vars(aligned, priority_arg, compat=compat)
372374
variables = merge_variables(expanded, priority_vars, compat=compat)
375+
assert_unique_multiindex_level_names(variables)
373376

374377
return variables
375378

@@ -431,6 +434,7 @@ def merge_core(objs, compat='broadcast_equals', join='outer', priority_arg=None,
431434

432435
priority_vars = _get_priority_vars(aligned, priority_arg, compat=compat)
433436
variables = merge_variables(expanded, priority_vars, compat=compat)
437+
assert_unique_multiindex_level_names(variables)
434438

435439
dims = calculate_dimensions(variables)
436440

xarray/core/variable.py

+26
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from datetime import timedelta
2+
from collections import defaultdict
23
import functools
34
import itertools
45
import warnings
@@ -1305,3 +1306,28 @@ def concat(variables, dim='concat_dim', positions=None, shortcut=False):
13051306
return Coordinate.concat(variables, dim, positions, shortcut)
13061307
else:
13071308
return Variable.concat(variables, dim, positions, shortcut)
1309+
1310+
1311+
def assert_unique_multiindex_level_names(variables):
1312+
"""Check for uniqueness of MultiIndex level names in all given
1313+
variables.
1314+
1315+
Not public API. Used for checking consistency of DataArray and Dataset
1316+
objects.
1317+
"""
1318+
level_names = defaultdict(list)
1319+
for var_name, var in variables.items():
1320+
if isinstance(var._data, PandasIndexAdapter):
1321+
idx_level_names = var.to_coord().level_names
1322+
if idx_level_names is not None:
1323+
for n in idx_level_names:
1324+
level_names[n].append(var_name)
1325+
1326+
duplicate_level_names = {k: v for k, v in level_names.items()
1327+
if len(v) > 1}
1328+
if duplicate_level_names:
1329+
duplicate_str = '\n'.join(['level %r found in %s'
1330+
% (k, ' and '.join(v))
1331+
for k, v in duplicate_level_names.items()])
1332+
raise ValueError('conflicting MultiIndex level names:\n%s'
1333+
% duplicate_str)

0 commit comments

Comments
 (0)