Skip to content

Commit 83a4b0f

Browse files
committed
BUG: get_level_values() on int level upcasts to Float64Index if needed
closes pandas-dev#17924
1 parent 51c5f4d commit 83a4b0f

File tree

3 files changed

+32
-20
lines changed

3 files changed

+32
-20
lines changed

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -970,6 +970,7 @@ Indexing
970970
- Fixes ``DataFrame.loc`` for setting with alignment and tz-aware ``DatetimeIndex`` (:issue:`16889`)
971971
- Avoids ``IndexError`` when passing an Index or Series to ``.iloc`` with older numpy (:issue:`17193`)
972972
- Allow unicode empty strings as placeholders in multilevel columns in Python 2 (:issue:`17099`)
973+
- Bug in :meth:`MultiIndex.get_level_values` which would return an invalid index on level of ints with missing values (:issue:`17924`)
973974
- Bug in ``.iloc`` when used with inplace addition or assignment and an int indexer on a ``MultiIndex`` causing the wrong indexes to be read from and written to (:issue:`17148`)
974975
- Bug in ``.isin()`` in which checking membership in empty ``Series`` objects raised an error (:issue:`16991`)
975976
- Bug in ``CategoricalIndex`` reindexing in which specified indices containing duplicates were not being respected (:issue:`17323`)

pandas/core/indexes/multi.py

+6-1
Original file line numberDiff line numberDiff line change
@@ -906,7 +906,12 @@ def _get_level_values(self, level):
906906
labels = self.labels[level]
907907
filled = algos.take_1d(unique._values, labels,
908908
fill_value=unique._na_value)
909-
values = unique._shallow_copy(filled)
909+
910+
if not unique._can_hold_na and filled.dtype == 'float':
911+
values = unique._shallow_copy_with_infer(filled)
912+
else:
913+
values = unique._shallow_copy(filled)
914+
910915
return values
911916

912917
def get_level_values(self, level):

pandas/tests/indexes/test_multi.py

+25-19
Original file line numberDiff line numberDiff line change
@@ -956,37 +956,43 @@ def test_get_level_values(self):
956956
tm.assert_index_equal(index.get_level_values(1), exp)
957957

958958
def test_get_level_values_na(self):
959+
# GH 17924
959960
arrays = [['a', 'b', 'b'], [1, np.nan, 2]]
960961
index = pd.MultiIndex.from_arrays(arrays)
961-
values = index.get_level_values(1)
962-
expected = np.array([1, np.nan, 2])
963-
tm.assert_numpy_array_equal(values.values.astype(float), expected)
962+
result = index.get_level_values(1)
963+
expected = pd.Index([1, np.nan, 2])
964+
tm.assert_index_equal(result, expected)
964965

965966
arrays = [['a', 'b', 'b'], [np.nan, np.nan, 2]]
966967
index = pd.MultiIndex.from_arrays(arrays)
967-
values = index.get_level_values(1)
968-
expected = np.array([np.nan, np.nan, 2])
969-
tm.assert_numpy_array_equal(values.values.astype(float), expected)
970-
971-
arrays = [[np.nan, np.nan, np.nan], ['a', np.nan, 1]]
972-
index = pd.MultiIndex.from_arrays(arrays)
973-
values = index.get_level_values(0)
974-
expected = np.array([np.nan, np.nan, np.nan])
975-
tm.assert_numpy_array_equal(values.values.astype(float), expected)
976-
values = index.get_level_values(1)
977-
expected = np.array(['a', np.nan, 1], dtype=object)
978-
tm.assert_numpy_array_equal(values.values, expected)
968+
result = index.get_level_values(1)
969+
expected = pd.Index([np.nan, np.nan, 2])
970+
tm.assert_index_equal(result, expected)
979971

980972
arrays = [['a', 'b', 'b'], pd.DatetimeIndex([0, 1, pd.NaT])]
981973
index = pd.MultiIndex.from_arrays(arrays)
982-
values = index.get_level_values(1)
974+
result = index.get_level_values(1)
983975
expected = pd.DatetimeIndex([0, 1, pd.NaT])
984-
tm.assert_numpy_array_equal(values.values, expected.values)
976+
tm.assert_index_equal(result, expected)
985977

986978
arrays = [[], []]
987979
index = pd.MultiIndex.from_arrays(arrays)
988-
values = index.get_level_values(0)
989-
assert values.shape == (0, )
980+
result = index.get_level_values(0)
981+
expected = pd.Index([], dtype=object)
982+
tm.assert_index_equal(result, expected)
983+
984+
@pytest.mark.xfail(reason='GH 17929 (empty level is casted to object')
985+
def test_get_level_values_all_na(self):
986+
arrays = [[np.nan, np.nan, np.nan], ['a', np.nan, 1]]
987+
index = pd.MultiIndex.from_arrays(arrays)
988+
result = index.get_level_values(0)
989+
# workaround for #17929 (should be 'float')
990+
expected = pd.Index([np.nan, np.nan, np.nan], dtype=np.float64)
991+
tm.assert_index_equal(result, expected)
992+
993+
result = index.get_level_values(1)
994+
expected = pd.Index(['a', np.nan, 1], dtype=object)
995+
tm.assert_index_equal(result, expected)
990996

991997
def test_reorder_levels(self):
992998
# this blows up

0 commit comments

Comments
 (0)