Add to_flat_index method to MultiIndex (#22866) · pandas-dev/pandas@454ecfc (original) (raw)
Navigation Menu
- Explore
- Pricing
Provide feedback
Saved searches
Use saved searches to filter your results more quickly
Appearance settings
Commit 454ecfc
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 |