Skip to content

Commit b758956

Browse files
committed
deprecate multiindex.is_lexsorted
1 parent b27caf0 commit b758956

File tree

9 files changed

+54
-39
lines changed

9 files changed

+54
-39
lines changed

pandas/core/indexes/multi.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -1809,6 +1809,15 @@ def _is_all_dates(self) -> bool:
18091809
return False
18101810

18111811
def is_lexsorted(self) -> bool:
1812+
warnings.warn(
1813+
"MultiIndex.is_lexsorted is deprecated as a public function, "
1814+
"users should use MultiIndex.is_monotonic_increasing instead.",
1815+
FutureWarning,
1816+
stacklevel=2,
1817+
)
1818+
return self._is_lexsorted()
1819+
1820+
def _is_lexsorted(self) -> bool:
18121821
"""
18131822
Return True if the codes are lexicographically sorted.
18141823
@@ -1821,23 +1830,23 @@ def is_lexsorted(self) -> bool:
18211830
In the below examples, the first level of the MultiIndex is sorted because
18221831
a<b<c, so there is no need to look at the next level.
18231832
1824-
>>> pd.MultiIndex.from_arrays([['a', 'b', 'c'], ['d', 'e', 'f']]).is_lexsorted()
1833+
>>> pd.MultiIndex.from_arrays([['a', 'b'], ['d', 'e']])._is_lexsorted()
18251834
True
1826-
>>> pd.MultiIndex.from_arrays([['a', 'b', 'c'], ['d', 'f', 'e']]).is_lexsorted()
1835+
>>> pd.MultiIndex.from_arrays([['a', 'b'], ['d', 'f']])._is_lexsorted()
18271836
True
18281837
18291838
In case there is a tie, the lexicographical sorting looks
18301839
at the next level of the MultiIndex.
18311840
1832-
>>> pd.MultiIndex.from_arrays([[0, 1, 1], ['a', 'b', 'c']]).is_lexsorted()
1841+
>>> pd.MultiIndex.from_arrays([[0, 1, 1], ['a', 'b', 'c']])._is_lexsorted()
18331842
True
1834-
>>> pd.MultiIndex.from_arrays([[0, 1, 1], ['a', 'c', 'b']]).is_lexsorted()
1843+
>>> pd.MultiIndex.from_arrays([[0, 1, 1], ['a', 'c', 'b']])._is_lexsorted()
18351844
False
18361845
>>> pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'],
1837-
... ['aa', 'bb', 'aa', 'bb']]).is_lexsorted()
1846+
... ['aa', 'bb', 'aa', 'bb']])._is_lexsorted()
18381847
True
18391848
>>> pd.MultiIndex.from_arrays([['a', 'a', 'b', 'b'],
1840-
... ['bb', 'aa', 'aa', 'bb']]).is_lexsorted()
1849+
... ['bb', 'aa', 'aa', 'bb']])._is_lexsorted()
18411850
False
18421851
"""
18431852
return self.lexsort_depth == self.nlevels
@@ -1898,7 +1907,7 @@ def _sort_levels_monotonic(self):
18981907
('b', 'bb')],
18991908
)
19001909
"""
1901-
if self.is_lexsorted() and self.is_monotonic:
1910+
if self._is_lexsorted() and self.is_monotonic:
19021911
return self
19031912

19041913
new_levels = []
@@ -3344,7 +3353,7 @@ def _reorder_indexer(
33443353
"""
33453354
# If the index is lexsorted and the list_like label in seq are sorted
33463355
# then we do not need to sort
3347-
if self.is_lexsorted():
3356+
if self._is_lexsorted():
33483357
need_sort = False
33493358
for i, k in enumerate(seq):
33503359
if is_list_like(k):

pandas/core/reshape/reshape.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -617,7 +617,7 @@ def _convert_level_number(level_num, columns):
617617
roll_columns = roll_columns.swaplevel(lev1, lev2)
618618
this.columns = roll_columns
619619

620-
if not this.columns.is_lexsorted():
620+
if not this.columns._is_lexsorted():
621621
# Workaround the edge case where 0 is one of the column names,
622622
# which interferes with trying to sort based on the first
623623
# level

pandas/tests/frame/methods/test_drop.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ def test_drop_multiindex_not_lexsorted(self):
162162
[("a", ""), ("b1", "c1"), ("b2", "c2")], names=["b", "c"]
163163
)
164164
lexsorted_df = DataFrame([[1, 3, 4]], columns=lexsorted_mi)
165-
assert lexsorted_df.columns.is_lexsorted()
165+
assert lexsorted_df.columns._is_lexsorted()
166166

167167
# define the non-lexsorted version
168168
not_lexsorted_df = DataFrame(
@@ -172,7 +172,7 @@ def test_drop_multiindex_not_lexsorted(self):
172172
index="a", columns=["b", "c"], values="d"
173173
)
174174
not_lexsorted_df = not_lexsorted_df.reset_index()
175-
assert not not_lexsorted_df.columns.is_lexsorted()
175+
assert not not_lexsorted_df.columns._is_lexsorted()
176176

177177
# compare the results
178178
tm.assert_frame_equal(lexsorted_df, not_lexsorted_df)

pandas/tests/frame/methods/test_sort_index.py

+10-10
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def test_sort_index_and_reconstruction_doc_example(self):
2424
levels=[["a", "b"], ["bb", "aa"]], codes=[[0, 0, 1, 1], [0, 1, 0, 1]]
2525
),
2626
)
27-
assert df.index.is_lexsorted()
27+
assert df.index._is_lexsorted()
2828
assert not df.index.is_monotonic
2929

3030
# sort it
@@ -35,15 +35,15 @@ def test_sort_index_and_reconstruction_doc_example(self):
3535
),
3636
)
3737
result = df.sort_index()
38-
assert result.index.is_lexsorted()
38+
assert result.index._is_lexsorted()
3939
assert result.index.is_monotonic
4040

4141
tm.assert_frame_equal(result, expected)
4242

4343
# reconstruct
4444
result = df.sort_index().copy()
4545
result.index = result.index._sort_levels_monotonic()
46-
assert result.index.is_lexsorted()
46+
assert result.index._is_lexsorted()
4747
assert result.index.is_monotonic
4848

4949
tm.assert_frame_equal(result, expected)
@@ -524,14 +524,14 @@ def test_sort_index_and_reconstruction(self):
524524
[(0.5, "a"), (0.5, "b"), (0.8, "a"), (0.8, "b")]
525525
),
526526
)
527-
assert expected.index.is_lexsorted()
527+
assert expected.index._is_lexsorted()
528528

529529
result = DataFrame(
530530
[[1, 1], [2, 2], [1, 1], [2, 2]],
531531
index=MultiIndex.from_product([[0.5, 0.8], list("ab")]),
532532
)
533533
result = result.sort_index()
534-
assert result.index.is_lexsorted()
534+
assert result.index._is_lexsorted()
535535
assert result.index.is_monotonic
536536

537537
tm.assert_frame_equal(result, expected)
@@ -543,14 +543,14 @@ def test_sort_index_and_reconstruction(self):
543543
),
544544
)
545545
result = result.sort_index()
546-
assert result.index.is_lexsorted()
546+
assert result.index._is_lexsorted()
547547

548548
tm.assert_frame_equal(result, expected)
549549

550550
concatted = pd.concat([df, df], keys=[0.8, 0.5])
551551
result = concatted.sort_index()
552552

553-
assert result.index.is_lexsorted()
553+
assert result.index._is_lexsorted()
554554
assert result.index.is_monotonic
555555

556556
tm.assert_frame_equal(result, expected)
@@ -567,13 +567,13 @@ def test_sort_index_and_reconstruction(self):
567567
df.columns = df.columns.set_levels(
568568
pd.to_datetime(df.columns.levels[1]), level=1
569569
)
570-
assert not df.columns.is_lexsorted()
570+
assert not df.columns._is_lexsorted()
571571
assert not df.columns.is_monotonic
572572
result = df.sort_index(axis=1)
573-
assert result.columns.is_lexsorted()
573+
assert result.columns._is_lexsorted()
574574
assert result.columns.is_monotonic
575575
result = df.sort_index(axis=1, level=1)
576-
assert result.columns.is_lexsorted()
576+
assert result.columns._is_lexsorted()
577577
assert result.columns.is_monotonic
578578

579579
# TODO: better name, de-duplicate with test_sort_index_level above

pandas/tests/groupby/test_groupby.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -1571,7 +1571,7 @@ def test_groupby_multiindex_not_lexsorted():
15711571
[("a", ""), ("b1", "c1"), ("b2", "c2")], names=["b", "c"]
15721572
)
15731573
lexsorted_df = DataFrame([[1, 3, 4]], columns=lexsorted_mi)
1574-
assert lexsorted_df.columns.is_lexsorted()
1574+
assert lexsorted_df.columns._is_lexsorted()
15751575

15761576
# define the non-lexsorted version
15771577
not_lexsorted_df = DataFrame(
@@ -1581,7 +1581,7 @@ def test_groupby_multiindex_not_lexsorted():
15811581
index="a", columns=["b", "c"], values="d"
15821582
)
15831583
not_lexsorted_df = not_lexsorted_df.reset_index()
1584-
assert not not_lexsorted_df.columns.is_lexsorted()
1584+
assert not not_lexsorted_df.columns._is_lexsorted()
15851585

15861586
# compare the results
15871587
tm.assert_frame_equal(lexsorted_df, not_lexsorted_df)
@@ -1596,7 +1596,7 @@ def test_groupby_multiindex_not_lexsorted():
15961596
df = DataFrame(
15971597
{"x": ["a", "a", "b", "a"], "y": [1, 1, 2, 2], "z": [1, 2, 3, 4]}
15981598
).set_index(["x", "y"])
1599-
assert not df.index.is_lexsorted()
1599+
assert not df.index._is_lexsorted()
16001600

16011601
for level in [0, 1, [0, 1]]:
16021602
for sort in [False, True]:

pandas/tests/indexes/multi/test_drop.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ def test_drop_not_lexsorted():
126126
# define the lexsorted version of the multi-index
127127
tuples = [("a", ""), ("b1", "c1"), ("b2", "c2")]
128128
lexsorted_mi = MultiIndex.from_tuples(tuples, names=["b", "c"])
129-
assert lexsorted_mi.is_lexsorted()
129+
assert lexsorted_mi._is_lexsorted()
130130

131131
# and the not-lexsorted version
132132
df = pd.DataFrame(
@@ -135,7 +135,7 @@ def test_drop_not_lexsorted():
135135
df = df.pivot_table(index="a", columns=["b", "c"], values="d")
136136
df = df.reset_index()
137137
not_lexsorted_mi = df.columns
138-
assert not not_lexsorted_mi.is_lexsorted()
138+
assert not not_lexsorted_mi._is_lexsorted()
139139

140140
# compare the results
141141
tm.assert_index_equal(lexsorted_mi, not_lexsorted_mi)

pandas/tests/indexes/multi/test_sorting.py

+8-8
Original file line numberDiff line numberDiff line change
@@ -131,27 +131,27 @@ def test_unsortedindex_doc_examples():
131131
with pytest.raises(UnsortedIndexError, match=msg):
132132
dfm.loc[(0, "y"):(1, "z")]
133133

134-
assert not dfm.index.is_lexsorted()
134+
assert not dfm.index._is_lexsorted()
135135
assert dfm.index.lexsort_depth == 1
136136

137137
# sort it
138138
dfm = dfm.sort_index()
139139
dfm.loc[(1, "z")]
140140
dfm.loc[(0, "y"):(1, "z")]
141141

142-
assert dfm.index.is_lexsorted()
142+
assert dfm.index._is_lexsorted()
143143
assert dfm.index.lexsort_depth == 2
144144

145145

146146
def test_reconstruct_sort():
147147

148148
# starts off lexsorted & monotonic
149149
mi = MultiIndex.from_arrays([["A", "A", "B", "B", "B"], [1, 2, 1, 2, 3]])
150-
assert mi.is_lexsorted()
150+
assert mi._is_lexsorted()
151151
assert mi.is_monotonic
152152

153153
recons = mi._sort_levels_monotonic()
154-
assert recons.is_lexsorted()
154+
assert recons._is_lexsorted()
155155
assert recons.is_monotonic
156156
assert mi is recons
157157

@@ -163,11 +163,11 @@ def test_reconstruct_sort():
163163
[("z", "a"), ("x", "a"), ("y", "b"), ("x", "b"), ("y", "a"), ("z", "b")],
164164
names=["one", "two"],
165165
)
166-
assert not mi.is_lexsorted()
166+
assert not mi._is_lexsorted()
167167
assert not mi.is_monotonic
168168

169169
recons = mi._sort_levels_monotonic()
170-
assert not recons.is_lexsorted()
170+
assert not recons._is_lexsorted()
171171
assert not recons.is_monotonic
172172

173173
assert mi.equals(recons)
@@ -179,11 +179,11 @@ def test_reconstruct_sort():
179179
codes=[[0, 1, 0, 2], [2, 0, 0, 1]],
180180
names=["col1", "col2"],
181181
)
182-
assert not mi.is_lexsorted()
182+
assert not mi._is_lexsorted()
183183
assert not mi.is_monotonic
184184

185185
recons = mi._sort_levels_monotonic()
186-
assert not recons.is_lexsorted()
186+
assert not recons._is_lexsorted()
187187
assert not recons.is_monotonic
188188

189189
assert mi.equals(recons)

pandas/tests/indexing/multiindex/test_sorted.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,16 @@ def test_frame_getitem_not_sorted2(self, key):
5050
with tm.assert_produces_warning(FutureWarning):
5151
return_value = df2.index.set_codes([0, 1, 0, 2], level="col1", inplace=True)
5252
assert return_value is None
53-
assert not df2.index.is_lexsorted()
53+
assert not df2.index._is_lexsorted()
5454
assert not df2.index.is_monotonic
5555

5656
assert df2_original.index.equals(df2.index)
5757
expected = df2.sort_index(key=key)
58-
assert expected.index.is_lexsorted()
58+
assert expected.index._is_lexsorted()
5959
assert expected.index.is_monotonic
6060

6161
result = df2.sort_index(level=0, key=key)
62-
assert result.index.is_lexsorted()
62+
assert result.index._is_lexsorted()
6363
assert result.index.is_monotonic
6464
tm.assert_frame_equal(result, expected)
6565

pandas/tests/test_multilevel.py

+8-2
Original file line numberDiff line numberDiff line change
@@ -401,11 +401,11 @@ def test_sort_non_lexsorted(self):
401401
)
402402

403403
df = DataFrame({"col": range(len(idx))}, index=idx, dtype="int64")
404-
assert df.index.is_lexsorted() is False
404+
assert df.index._is_lexsorted() is False
405405
assert df.index.is_monotonic is False
406406

407407
sorted = df.sort_index()
408-
assert sorted.index.is_lexsorted() is True
408+
assert sorted.index._is_lexsorted() is True
409409
assert sorted.index.is_monotonic is True
410410

411411
expected = DataFrame(
@@ -417,3 +417,9 @@ def test_sort_non_lexsorted(self):
417417
)
418418
result = sorted.loc[pd.IndexSlice["B":"C", "a":"c"], :]
419419
tm.assert_frame_equal(result, expected)
420+
421+
422+
def test_is_lexsorted_deprecation():
423+
# GH 32259
424+
with tm.assert_produces_warning():
425+
MultiIndex.from_arrays([["a", "b", "c"], ["d", "f", "e"]]).is_lexsorted()

0 commit comments

Comments
 (0)