Skip to content

Commit f7935c2

Browse files
committed
API: harmonize Index.to_flat_index to MultiIndex.to_flat_index
closes #23670
1 parent 683c7b5 commit f7935c2

File tree

5 files changed

+26
-50
lines changed

5 files changed

+26
-50
lines changed

doc/source/whatsnew/v0.24.2.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ Bug Fixes
4545

4646
**Indexing**
4747

48-
-
48+
- :meth:`Index.to_flat_index` now always returns an :class:`Index` containing tuples, even in the case the original object was already a flat :class:`Index` (:issue:`23670`).
4949
-
5050
-
5151

pandas/core/indexes/base.py

+16-8
Original file line numberDiff line numberDiff line change
@@ -1105,23 +1105,31 @@ def summary(self, name=None):
11051105

11061106
def to_flat_index(self):
11071107
"""
1108-
Identity method.
1108+
Convert a MultiIndex to an Index of Tuples containing the level values.
11091109
11101110
.. versionadded:: 0.24.0
11111111
1112-
This is implemented for compatability with subclass implementations
1113-
when chaining.
1114-
11151112
Returns
11161113
-------
11171114
pd.Index
1118-
Caller.
1115+
Index with the MultiIndex data represented in Tuples.
11191116
1120-
See Also
1117+
Examples
11211118
--------
1122-
MultiIndex.to_flat_index : Subclass implementation.
1119+
>>> index = pd.MultiIndex.from_product(
1120+
... [['foo', 'bar'], ['baz', 'qux']],
1121+
... names=['a', 'b'])
1122+
>>> index.to_flat_index()
1123+
Index([('foo', 'baz'), ('foo', 'qux'),
1124+
('bar', 'baz'), ('bar', 'qux')],
1125+
dtype='object')
11231126
"""
1124-
return self
1127+
1128+
from .multi import MultiIndex
1129+
if not isinstance(self, MultiIndex):
1130+
self = MultiIndex.from_product([self])
1131+
1132+
return Index(self.values, tupleize_cols=False)
11251133

11261134
def to_series(self, index=None, name=None):
11271135
"""

pandas/core/indexes/multi.py

-29
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,6 @@ class MultiIndex(Index):
164164
set_levels
165165
set_codes
166166
to_frame
167-
to_flat_index
168167
is_lexsorted
169168
sortlevel
170169
droplevel
@@ -1523,34 +1522,6 @@ def to_hierarchical(self, n_repeat, n_shuffle=1):
15231522
FutureWarning, stacklevel=2)
15241523
return MultiIndex(levels=levels, codes=codes, names=names)
15251524

1526-
def to_flat_index(self):
1527-
"""
1528-
Convert a MultiIndex to an Index of Tuples containing the level values.
1529-
1530-
.. versionadded:: 0.24.0
1531-
1532-
Returns
1533-
-------
1534-
pd.Index
1535-
Index with the MultiIndex data represented in Tuples.
1536-
1537-
Notes
1538-
-----
1539-
This method will simply return the caller if called by anything other
1540-
than a MultiIndex.
1541-
1542-
Examples
1543-
--------
1544-
>>> index = pd.MultiIndex.from_product(
1545-
... [['foo', 'bar'], ['baz', 'qux']],
1546-
... names=['a', 'b'])
1547-
>>> index.to_flat_index()
1548-
Index([('foo', 'baz'), ('foo', 'qux'),
1549-
('bar', 'baz'), ('bar', 'qux')],
1550-
dtype='object')
1551-
"""
1552-
return Index(self.values, tupleize_cols=False)
1553-
15541525
@property
15551526
def is_all_dates(self):
15561527
return False

pandas/tests/indexes/multi/test_conversion.py

-8
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,3 @@ def test_to_series_with_arguments(idx):
214214
assert s.values is not idx.values
215215
assert s.index is not idx
216216
assert s.name != idx.name
217-
218-
219-
def test_to_flat_index(idx):
220-
expected = pd.Index((('foo', 'one'), ('foo', 'two'), ('bar', 'one'),
221-
('baz', 'two'), ('qux', 'one'), ('qux', 'two')),
222-
tupleize_cols=False)
223-
result = idx.to_flat_index()
224-
tm.assert_index_equal(result, expected)

pandas/tests/indexes/test_common.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,17 @@ def test_corner_union(self, indices, fname, sname, expected_name):
113113
tm.assert_index_equal(union, expected)
114114

115115
def test_to_flat_index(self, indices):
116-
# 22866
117-
if isinstance(indices, MultiIndex):
118-
pytest.skip("Separate expectation for MultiIndex")
116+
# 22866, 23670
119117

120118
result = indices.to_flat_index()
121-
tm.assert_index_equal(result, indices)
119+
120+
if isinstance(indices, MultiIndex):
121+
values = [tuple(v) for v in indices]
122+
else:
123+
values = [(v,) for v in indices]
124+
expected = pd.Index(values, tupleize_cols=False)
125+
126+
tm.assert_index_equal(result, expected)
122127

123128
def test_wrong_number_names(self, indices):
124129
with pytest.raises(ValueError, match="^Length"):

0 commit comments

Comments
 (0)