Add to_flat_index method to MultiIndex (#22866) · pandas-dev/pandas@454ecfc (original) (raw)

Skip to content

Provide feedback

Saved searches

Use saved searches to filter your results more quickly

Sign up

Appearance settings

Commit 454ecfc

WillAydTomAugspurger

authored and

committed

Add to_flat_index method to MultiIndex (#22866)

File tree

6 files changed

lines changed

6 files changed

lines changed

Original file line number Diff line number Diff line change
@@ -1724,6 +1724,7 @@ MultiIndex Components
1724 1724 MultiIndex.set_levels
1725 1725 MultiIndex.set_labels
1726 1726 MultiIndex.to_hierarchical
1727 + MultiIndex.to_flat_index
1727 1728 MultiIndex.to_frame
1728 1729 MultiIndex.is_lexsorted
1729 1730 MultiIndex.sortlevel
Original file line number Diff line number Diff line change
@@ -238,6 +238,7 @@ Other Enhancements
238 238 - :func:`~DataFrame.to_parquet` now supports writing a ``DataFrame`` as a directory of parquet files partitioned by a subset of the columns when ``engine = 'pyarrow'`` (:issue:`23283`)
239 239 - :meth:`Timestamp.tz_localize`, :meth:`DatetimeIndex.tz_localize`, and :meth:`Series.tz_localize` have gained the ``nonexistent`` argument for alternative handling of nonexistent times. See :ref:`timeseries.timezone_nonexistent` (:issue:`8917`)
240 240 - :meth:`read_excel()` now accepts ``usecols`` as a list of column names or callable (:issue:`18273`)
241 +- :meth:`MultiIndex.to_flat_index` has been added to flatten multiple levels into a single-level :class:`Index` object.
241 242
242 243 .. _whatsnew_0240.api_breaking:
243 244
Original file line number Diff line number Diff line change
@@ -1113,6 +1113,26 @@ def _format_attrs(self):
1113 1113 """
1114 1114 return format_object_attrs(self)
1115 1115
1116 +def to_flat_index(self):
1117 +"""
1118 + Identity method.
1119 +
1120 + .. versionadded:: 0.24.0
1121 +
1122 + This is implemented for compatability with subclass implementations
1123 + when chaining.
1124 +
1125 + Returns
1126 + -------
1127 + pd.Index
1128 + Caller.
1129 +
1130 + See Also
1131 + --------
1132 + MultiIndex.to_flat_index : Subclass implementation.
1133 + """
1134 +return self
1135 +
1116 1136 def to_series(self, index=None, name=None):
1117 1137 """
1118 1138 Create a Series with both index and values equal to the index keys
Original file line number Diff line number Diff line change
@@ -193,6 +193,7 @@ class MultiIndex(Index):
193 193 set_levels
194 194 set_labels
195 195 to_frame
196 + to_flat_index
196 197 is_lexsorted
197 198 sortlevel
198 199 droplevel
@@ -1246,6 +1247,34 @@ def to_hierarchical(self, n_repeat, n_shuffle=1):
1246 1247 FutureWarning, stacklevel=2)
1247 1248 return MultiIndex(levels=levels, labels=labels, names=names)
1248 1249
1250 +def to_flat_index(self):
1251 +"""
1252 + Convert a MultiIndex to an Index of Tuples containing the level values.
1253 +
1254 + .. versionadded:: 0.24.0
1255 +
1256 + Returns
1257 + -------
1258 + pd.Index
1259 + Index with the MultiIndex data represented in Tuples.
1260 +
1261 + Notes
1262 + -----
1263 + This method will simply return the caller if called by anything other
1264 + than a MultiIndex.
1265 +
1266 + Examples
1267 + --------
1268 + >>> index = pd.MultiIndex.from_product(
1269 + ... [['foo', 'bar'], ['baz', 'qux']],
1270 + ... names=['a', 'b'])
1271 + >>> index.to_flat_index()
1272 + Index([('foo', 'baz'), ('foo', 'qux'),
1273 + ('bar', 'baz'), ('bar', 'qux')],
1274 + dtype='object')
1275 + """
1276 +return Index(self.values, tupleize_cols=False)
1277 +
1249 1278 @property
1250 1279 def is_all_dates(self):
1251 1280 return False
Original file line number Diff line number Diff line change
@@ -170,3 +170,11 @@ def test_to_series_with_arguments(idx):
170 170 assert s.values is not idx.values
171 171 assert s.index is not idx
172 172 assert s.name != idx.name
173 +
174 +
175 +def test_to_flat_index(idx):
176 +expected = pd.Index((('foo', 'one'), ('foo', 'two'), ('bar', 'one'),
177 + ('baz', 'two'), ('qux', 'one'), ('qux', 'two')),
178 +tupleize_cols=False)
179 +result = idx.to_flat_index()
180 +tm.assert_index_equal(result, expected)
Original file line number Diff line number Diff line change
@@ -2266,6 +2266,14 @@ def test_tab_complete_warning(self, ip):
2266 2266 with provisionalcompleter('ignore'):
2267 2267 list(ip.Completer.completions('idx.', 4))
2268 2268
2269 +def test_to_flat_index(self, indices):
2270 +# 22866
2271 +if isinstance(indices, MultiIndex):
2272 +pytest.skip("Separate expectation for MultiIndex")
2273 +
2274 +result = indices.to_flat_index()
2275 +tm.assert_index_equal(result, indices)
2276 +
2269 2277
2270 2278 class TestMixedIntIndex(Base):
2271 2279 # Mostly the tests from common.py for which the results differ