Skip to content

Commit 80a4959

Browse files
committed
MultiIndex.set_labels -> set_codes
1 parent ea18e1a commit 80a4959

File tree

5 files changed

+118
-63
lines changed

5 files changed

+118
-63
lines changed

pandas/core/indexes/multi.py

+23-13
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
_index_shared_docs)
4343
from pandas.core.indexes.frozen import FrozenList, _ensure_frozen
4444
import pandas.core.indexes.base as ibase
45+
from pandas.util._decorators import deprecate_kwarg
4546
_index_doc_kwargs = dict(ibase._index_doc_kwargs)
4647
_index_doc_kwargs.update(
4748
dict(klass='MultiIndex',
@@ -264,8 +265,8 @@ def _verify_integrity(self, codes=None, levels=None):
264265
Raises
265266
------
266267
ValueError
267-
If length of levels and codes don't match, if any code would
268-
exceed level bounds, or there are any duplicate levels.
268+
If length of levels and codes don't match, if the codes for any
269+
level would exceed level bounds, or there are any duplicate levels.
269270
"""
270271
# NOTE: Currently does not check, among other things, that cached
271272
# nlevels matches nor that sortorder matches actually sortorder.
@@ -453,14 +454,23 @@ def _set_codes(self, codes, level=None, copy=False, validate=True,
453454

454455
def set_labels(self, labels, level=None, inplace=False,
455456
verify_integrity=True):
457+
warnings.warn(("set_labels was deprecated in version 0.24.0."
458+
"Use set_codes instead."),
459+
FutureWarning, stacklevel=2)
460+
return self.set_codes(labels, level=level, inplace=inplace,
461+
verify_integrity=verify_integrity)
462+
463+
@deprecate_kwarg(old_arg_name='labels', new_arg_name='codes')
464+
def set_codes(self, codes, level=None, inplace=False,
465+
verify_integrity=True):
456466
"""
457-
Set new labels on MultiIndex. Defaults to returning
467+
Set new codes on MultiIndex. Defaults to returning
458468
new index.
459469
460470
Parameters
461471
----------
462-
labels : sequence or list of sequence
463-
new labels to apply
472+
codes : sequence or list of sequence
473+
new codes to apply
464474
level : int, level name, or sequence of int/level names (default None)
465475
level(s) to set (None for all levels)
466476
inplace : bool
@@ -495,22 +505,22 @@ def set_labels(self, labels, level=None, inplace=False,
495505
names=[u'foo', u'bar'])
496506
"""
497507
if level is not None and not is_list_like(level):
498-
if not is_list_like(labels):
499-
raise TypeError("Labels must be list-like")
500-
if is_list_like(labels[0]):
501-
raise TypeError("Labels must be list-like")
508+
if not is_list_like(codes):
509+
raise TypeError("Codes must be list-like")
510+
if is_list_like(codes[0]):
511+
raise TypeError("Codes must be list-like")
502512
level = [level]
503-
labels = [labels]
513+
codes = [codes]
504514
elif level is None or is_list_like(level):
505-
if not is_list_like(labels) or not is_list_like(labels[0]):
506-
raise TypeError("Labels must be list of lists-like")
515+
if not is_list_like(codes) or not is_list_like(codes[0]):
516+
raise TypeError("Codes must be list of lists-like")
507517

508518
if inplace:
509519
idx = self
510520
else:
511521
idx = self._shallow_copy()
512522
idx._reset_identity()
513-
idx._set_codes(labels, level=level, verify_integrity=verify_integrity)
523+
idx._set_codes(codes, level=level, verify_integrity=verify_integrity)
514524
if not inplace:
515525
return idx
516526

pandas/tests/indexes/multi/test_compat.py

+2-2
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

+1-1
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

+91-46
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'):

pandas/tests/test_multilevel.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2596,7 +2596,7 @@ def test_frame_getitem_not_sorted2(self):
25962596
df2_original = df2.copy()
25972597

25982598
df2.index.set_levels(['b', 'd', 'a'], level='col1', inplace=True)
2599-
df2.index.set_labels([0, 1, 0, 2], level='col1', inplace=True)
2599+
df2.index.set_codes([0, 1, 0, 2], level='col1', inplace=True)
26002600
assert not df2.index.is_lexsorted()
26012601
assert not df2.index.is_monotonic
26022602

0 commit comments

Comments
 (0)