Skip to content

Commit 4672448

Browse files
author
Benoit Bovy
committed
rewritten checking uniqueness of multi-index level names
1 parent c03dfa4 commit 4672448

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 deep_align
44
from .utils import Frozen
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_only(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

@@ -319,6 +321,7 @@ def align_and_merge_coords(objs, compat='minimal', join='outer',
319321
expanded = expand_variable_dicts(aligned)
320322
priority_vars = _get_priority_vars(aligned, priority_arg, compat=compat)
321323
variables = merge_variables(expanded, priority_vars, compat=compat)
324+
assert_unique_multiindex_level_names(variables)
322325

323326
return variables
324327

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

381384
priority_vars = _get_priority_vars(aligned, priority_arg, compat=compat)
382385
variables = merge_variables(expanded, priority_vars, compat=compat)
386+
assert_unique_multiindex_level_names(variables)
383387

384388
dims = calculate_dimensions(variables)
385389

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
@@ -1297,3 +1298,28 @@ def concat(variables, dim='concat_dim', positions=None, shortcut=False):
12971298
return Coordinate.concat(variables, dim, positions, shortcut)
12981299
else:
12991300
return Variable.concat(variables, dim, positions, shortcut)
1301+
1302+
1303+
def assert_unique_multiindex_level_names(variables):
1304+
"""Check for uniqueness of MultiIndex level names in all given
1305+
variables.
1306+
1307+
Not public API. Used for checking consistency of DataArray and Dataset
1308+
objects.
1309+
"""
1310+
level_names = defaultdict(list)
1311+
for var_name, var in variables.items():
1312+
if isinstance(var._data, PandasIndexAdapter):
1313+
idx_level_names = var.to_coord().level_names
1314+
if idx_level_names is not None:
1315+
for n in idx_level_names:
1316+
level_names[n].append(var_name)
1317+
1318+
duplicate_level_names = {k: v for k, v in level_names.items()
1319+
if len(v) > 1}
1320+
if duplicate_level_names:
1321+
duplicate_str = '\n'.join(['level %r found in %s'
1322+
% (k, ' and '.join(v))
1323+
for k, v in duplicate_level_names.items()])
1324+
raise ValueError('conflicting MultiIndex level names:\n%s'
1325+
% duplicate_str)

0 commit comments

Comments
 (0)