Skip to content

Commit e91486e

Browse files
committed
MultiIndex.set_labels -> set_codes
1 parent 8da59fb commit e91486e

File tree

4 files changed

+118
-62
lines changed

4 files changed

+118
-62
lines changed

pandas/core/indexes/multi.py

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@
3232

3333
from pandas.io.formats.printing import pprint_thing
3434

35+
from pandas.util._decorators import deprecate_kwarg
36+
3537
_index_doc_kwargs = dict(ibase._index_doc_kwargs)
3638
_index_doc_kwargs.update(
3739
dict(klass='MultiIndex',
@@ -254,8 +256,8 @@ def _verify_integrity(self, codes=None, levels=None):
254256
Raises
255257
------
256258
ValueError
257-
If length of levels and codes don't match, if any code would
258-
exceed level bounds, or there are any duplicate levels.
259+
If length of levels and codes don't match, if the codes for any
260+
level would exceed level bounds, or there are any duplicate levels.
259261
"""
260262
# NOTE: Currently does not check, among other things, that cached
261263
# nlevels matches nor that sortorder matches actually sortorder.
@@ -442,14 +444,23 @@ def _set_codes(self, codes, level=None, copy=False, validate=True,
442444

443445
def set_labels(self, labels, level=None, inplace=False,
444446
verify_integrity=True):
447+
warnings.warn(("set_labels was deprecated in version 0.24.0."
448+
"Use set_codes instead."),
449+
FutureWarning, stacklevel=2)
450+
return self.set_codes(labels, level=level, inplace=inplace,
451+
verify_integrity=verify_integrity)
452+
453+
@deprecate_kwarg(old_arg_name='labels', new_arg_name='codes')
454+
def set_codes(self, codes, level=None, inplace=False,
455+
verify_integrity=True):
445456
"""
446-
Set new labels on MultiIndex. Defaults to returning
457+
Set new codes on MultiIndex. Defaults to returning
447458
new index.
448459
449460
Parameters
450461
----------
451-
labels : sequence or list of sequence
452-
new labels to apply
462+
codes : sequence or list of sequence
463+
new codes to apply
453464
level : int, level name, or sequence of int/level names (default None)
454465
level(s) to set (None for all levels)
455466
inplace : bool
@@ -484,22 +495,22 @@ def set_labels(self, labels, level=None, inplace=False,
484495
names=[u'foo', u'bar'])
485496
"""
486497
if level is not None and not is_list_like(level):
487-
if not is_list_like(labels):
488-
raise TypeError("Labels must be list-like")
489-
if is_list_like(labels[0]):
490-
raise TypeError("Labels must be list-like")
498+
if not is_list_like(codes):
499+
raise TypeError("Codes must be list-like")
500+
if is_list_like(codes[0]):
501+
raise TypeError("Codes must be list-like")
491502
level = [level]
492-
labels = [labels]
503+
codes = [codes]
493504
elif level is None or is_list_like(level):
494-
if not is_list_like(labels) or not is_list_like(labels[0]):
495-
raise TypeError("Labels must be list of lists-like")
505+
if not is_list_like(codes) or not is_list_like(codes[0]):
506+
raise TypeError("Codes must be list of lists-like")
496507

497508
if inplace:
498509
idx = self
499510
else:
500511
idx = self._shallow_copy()
501512
idx._reset_identity()
502-
idx._set_codes(labels, level=level, verify_integrity=verify_integrity)
513+
idx._set_codes(codes, level=level, verify_integrity=verify_integrity)
503514
if not inplace:
504515
return idx
505516

pandas/tests/indexes/multi/test_compat.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ def test_inplace_mutation_resets_values():
9292

9393
# Must be 1d array of tuples
9494
assert exp_values.shape == (6,)
95-
new_values = mi2.set_labels(labels2).values
95+
new_values = mi2.set_codes(labels2).values
9696

9797
# Not inplace shouldn't change
9898
tm.assert_almost_equal(mi2._tuples, vals2)
@@ -101,7 +101,7 @@ def test_inplace_mutation_resets_values():
101101
tm.assert_almost_equal(exp_values, new_values)
102102

103103
# ...and again setting inplace should kill _tuples, etc
104-
mi2.set_labels(labels2, inplace=True)
104+
mi2.set_codes(labels2, inplace=True)
105105
tm.assert_almost_equal(mi2.values, new_values)
106106

107107

pandas/tests/indexes/multi/test_constructor.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ def test_constructor_mismatched_label_levels(idx):
8282
idx.copy().set_levels([['a'], ['b']])
8383

8484
with pytest.raises(ValueError, match=label_error):
85-
idx.copy().set_labels([[0, 0, 0, 0], [0, 0]])
85+
idx.copy().set_codes([[0, 0, 0, 0], [0, 0]])
8686

8787

8888
def test_copy_in_constructor():

pandas/tests/indexes/multi/test_get_set.py

Lines changed: 91 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ def test_set_levels_labels_directly(idx):
171171

172172

173173
def test_set_levels(idx):
174-
# side note - you probably wouldn't want to use levels and labels
174+
# side note - you probably wouldn't want to use levels and codes
175175
# directly like this - but it is possible.
176176
levels = idx.levels
177177
new_levels = [[lev + 'a' for lev in level] for level in levels]
@@ -231,9 +231,15 @@ def test_set_levels(idx):
231231
assert_matching(idx.levels, original_index.levels,
232232
check_dtype=True)
233233

234+
<<<<<<< HEAD
234235
with pytest.raises(ValueError, match="^On"):
235236
idx.set_labels([0, 1, 2, 3, 4, 5], level=0,
236237
inplace=inplace)
238+
=======
239+
with tm.assert_raises_regex(ValueError, "^On"):
240+
idx.set_codes([0, 1, 2, 3, 4, 5], level=0,
241+
inplace=inplace)
242+
>>>>>>> MultiIndex.set_labels -> set_codes
237243
assert_matching(idx.labels, original_index.labels,
238244
check_dtype=True)
239245

@@ -242,92 +248,118 @@ def test_set_levels(idx):
242248
assert_matching(idx.levels, original_index.levels,
243249
check_dtype=True)
244250

251+
<<<<<<< HEAD
245252
with pytest.raises(TypeError, match="^Labels"):
246253
idx.set_labels(1, level=0, inplace=inplace)
254+
=======
255+
with tm.assert_raises_regex(TypeError, "^Codes"):
256+
idx.set_codes(1, level=0, inplace=inplace)
257+
>>>>>>> MultiIndex.set_labels -> set_codes
247258
assert_matching(idx.labels, original_index.labels,
248259
check_dtype=True)
249260

250261

251-
def test_set_labels(idx):
252-
# side note - you probably wouldn't want to use levels and labels
262+
def test_set_codes(idx):
263+
# side note - you probably wouldn't want to use levels and codes
253264
# directly like this - but it is possible.
254-
labels = idx.labels
255-
major_labels, minor_labels = labels
256-
major_labels = [(x + 1) % 3 for x in major_labels]
257-
minor_labels = [(x + 1) % 1 for x in minor_labels]
258-
new_labels = [major_labels, minor_labels]
259-
260-
# label changing [w/o mutation]
261-
ind2 = idx.set_labels(new_labels)
262-
assert_matching(ind2.labels, new_labels)
263-
assert_matching(idx.labels, labels)
264-
265-
# label changing [w/ mutation]
265+
codes = idx.labels
266+
major_codes, minor_codes = codes
267+
major_codes = [(x + 1) % 3 for x in major_codes]
268+
minor_codes = [(x + 1) % 1 for x in minor_codes]
269+
new_codes = [major_codes, minor_codes]
270+
271+
# changing codes w/o mutation
272+
ind2 = idx.set_codes(new_codes)
273+
assert_matching(ind2.labels, new_codes)
274+
assert_matching(idx.labels, codes)
275+
276+
# changing label w/ mutation
266277
ind2 = idx.copy()
267-
inplace_return = ind2.set_labels(new_labels, inplace=True)
278+
inplace_return = ind2.set_codes(new_codes, inplace=True)
268279
assert inplace_return is None
269-
assert_matching(ind2.labels, new_labels)
280+
assert_matching(ind2.labels, new_codes)
270281

271-
# label changing specific level [w/o mutation]
272-
ind2 = idx.set_labels(new_labels[0], level=0)
273-
assert_matching(ind2.labels, [new_labels[0], labels[1]])
274-
assert_matching(idx.labels, labels)
282+
# codes changing specific level w/o mutation
283+
ind2 = idx.set_codes(new_codes[0], level=0)
284+
assert_matching(ind2.labels, [new_codes[0], codes[1]])
285+
assert_matching(idx.labels, codes)
275286

276-
ind2 = idx.set_labels(new_labels[1], level=1)
277-
assert_matching(ind2.labels, [labels[0], new_labels[1]])
278-
assert_matching(idx.labels, labels)
287+
ind2 = idx.set_codes(new_codes[1], level=1)
288+
assert_matching(ind2.labels, [codes[0], new_codes[1]])
289+
assert_matching(idx.labels, codes)
279290

280-
# label changing multiple levels [w/o mutation]
281-
ind2 = idx.set_labels(new_labels, level=[0, 1])
282-
assert_matching(ind2.labels, new_labels)
283-
assert_matching(idx.labels, labels)
291+
# codes changing multiple levels w/o mutation
292+
ind2 = idx.set_codes(new_codes, level=[0, 1])
293+
assert_matching(ind2.labels, new_codes)
294+
assert_matching(idx.labels, codes)
284295

285-
# label changing specific level [w/ mutation]
296+
# label changing specific level w/ mutation
286297
ind2 = idx.copy()
287-
inplace_return = ind2.set_labels(new_labels[0], level=0, inplace=True)
298+
inplace_return = ind2.set_codes(new_codes[0], level=0, inplace=True)
288299
assert inplace_return is None
289-
assert_matching(ind2.labels, [new_labels[0], labels[1]])
290-
assert_matching(idx.labels, labels)
300+
assert_matching(ind2.labels, [new_codes[0], codes[1]])
301+
assert_matching(idx.labels, codes)
291302

292303
ind2 = idx.copy()
293-
inplace_return = ind2.set_labels(new_labels[1], level=1, inplace=True)
304+
inplace_return = ind2.set_codes(new_codes[1], level=1, inplace=True)
294305
assert inplace_return is None
295-
assert_matching(ind2.labels, [labels[0], new_labels[1]])
296-
assert_matching(idx.labels, labels)
306+
assert_matching(ind2.labels, [codes[0], new_codes[1]])
307+
assert_matching(idx.labels, codes)
297308

298-
# label changing multiple levels [w/ mutation]
309+
# codes changing multiple levels [w/ mutation]
299310
ind2 = idx.copy()
300-
inplace_return = ind2.set_labels(new_labels, level=[0, 1],
301-
inplace=True)
311+
inplace_return = ind2.set_codes(new_codes, level=[0, 1],
312+
inplace=True)
302313
assert inplace_return is None
303-
assert_matching(ind2.labels, new_labels)
304-
assert_matching(idx.labels, labels)
314+
assert_matching(ind2.labels, new_codes)
315+
assert_matching(idx.labels, codes)
305316

306317
# label changing for levels of different magnitude of categories
318+
ind = pd.MultiIndex.from_tuples([(0, i) for i in range(130)])
319+
new_codes = range(129, -1, -1)
320+
expected = pd.MultiIndex.from_tuples(
321+
[(0, i) for i in new_codes])
322+
323+
# [w/o mutation]
324+
result = ind.set_codes(codes=new_codes, level=1)
325+
assert result.equals(expected)
326+
327+
# [w/ mutation]
328+
result = ind.copy()
329+
result.set_codes(codes=new_codes, level=1, inplace=True)
330+
assert result.equals(expected)
331+
332+
with tm.assert_produces_warning(FutureWarning):
333+
ind.set_codes(labels=new_codes, level=1)
334+
335+
336+
def test_set_labels_deprecated():
307337
ind = pd.MultiIndex.from_tuples([(0, i) for i in range(130)])
308338
new_labels = range(129, -1, -1)
309339
expected = pd.MultiIndex.from_tuples(
310340
[(0, i) for i in new_labels])
311341

312342
# [w/o mutation]
313-
result = ind.set_labels(labels=new_labels, level=1)
343+
with tm.assert_produces_warning(FutureWarning):
344+
result = ind.set_labels(labels=new_labels, level=1)
314345
assert result.equals(expected)
315346

316347
# [w/ mutation]
317348
result = ind.copy()
318-
result.set_labels(labels=new_labels, level=1, inplace=True)
349+
with tm.assert_produces_warning(FutureWarning):
350+
result.set_labels(labels=new_labels, level=1, inplace=True)
319351
assert result.equals(expected)
320352

321353

322-
def test_set_levels_labels_names_bad_input(idx):
323-
levels, labels = idx.levels, idx.labels
354+
def test_set_levels_codes_names_bad_input(idx):
355+
levels, codes = idx.levels, idx.labels
324356
names = idx.names
325357

326358
with pytest.raises(ValueError, match='Length of levels'):
327359
idx.set_levels([levels[0]])
328360

329-
with pytest.raises(ValueError, match='Length of labels'):
330-
idx.set_labels([labels[0]])
361+
with tm.assert_raises_regex(ValueError, 'Length of codes'):
362+
idx.set_codes([codes[0]])
331363

332364
with pytest.raises(ValueError, match='Length of names'):
333365
idx.set_names([names[0]])
@@ -337,8 +369,13 @@ def test_set_levels_labels_names_bad_input(idx):
337369
idx.set_levels(levels[0])
338370

339371
# shouldn't scalar data error, instead should demand list-like
372+
<<<<<<< HEAD
340373
with pytest.raises(TypeError, match='list of lists-like'):
341374
idx.set_labels(labels[0])
375+
=======
376+
with tm.assert_raises_regex(TypeError, 'list of lists-like'):
377+
idx.set_codes(codes[0])
378+
>>>>>>> MultiIndex.set_labels -> set_codes
342379

343380
# shouldn't scalar data error, instead should demand list-like
344381
with pytest.raises(TypeError, match='list-like'):
@@ -352,11 +389,19 @@ def test_set_levels_labels_names_bad_input(idx):
352389
idx.set_levels(levels, level=0)
353390

354391
# should have equal lengths
392+
<<<<<<< HEAD
355393
with pytest.raises(TypeError, match='list of lists-like'):
356394
idx.set_labels(labels[0], level=[0, 1])
357395

358396
with pytest.raises(TypeError, match='list-like'):
359397
idx.set_labels(labels, level=0)
398+
=======
399+
with tm.assert_raises_regex(TypeError, 'list of lists-like'):
400+
idx.set_codes(codes[0], level=[0, 1])
401+
402+
with tm.assert_raises_regex(TypeError, 'list-like'):
403+
idx.set_codes(codes, level=0)
404+
>>>>>>> MultiIndex.set_labels -> set_codes
360405

361406
# should have equal lengths
362407
with pytest.raises(ValueError, match='Length of names'):

0 commit comments

Comments
 (0)