Skip to content

Commit 10d7efa

Browse files
committed
BUG: get_level_values() on int level upcasts to Float64Index if needed
closes #17924
1 parent 51c5f4d commit 10d7efa

File tree

3 files changed

+26
-17
lines changed

3 files changed

+26
-17
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 ``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 = Index(filled, copy=False, **unique._get_attributes_dict())
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

+19-16
Original file line numberDiff line numberDiff line change
@@ -956,37 +956,40 @@ 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)
968+
result = index.get_level_values(1)
969+
expected = pd.Index([np.nan, np.nan, 2])
970+
tm.assert_index_equal(result, expected)
970971

971972
arrays = [[np.nan, np.nan, np.nan], ['a', np.nan, 1]]
972973
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)
974+
result = index.get_level_values(0)
975+
# workaround for #17929 (should be 'float')
976+
expected = pd.Index([np.nan, np.nan, np.nan], dtype='object')
977+
tm.assert_index_equal(result, expected)
978+
979+
result = index.get_level_values(1)
980+
expected = pd.Index(['a', np.nan, 1], dtype=object)
981+
tm.assert_index_equal(result, expected)
979982

980983
arrays = [['a', 'b', 'b'], pd.DatetimeIndex([0, 1, pd.NaT])]
981984
index = pd.MultiIndex.from_arrays(arrays)
982-
values = index.get_level_values(1)
985+
result = index.get_level_values(1)
983986
expected = pd.DatetimeIndex([0, 1, pd.NaT])
984-
tm.assert_numpy_array_equal(values.values, expected.values)
987+
tm.assert_index_equal(result, expected)
985988

986989
arrays = [[], []]
987990
index = pd.MultiIndex.from_arrays(arrays)
988-
values = index.get_level_values(0)
989-
assert values.shape == (0, )
991+
result = index.get_level_values(0)
992+
assert result.shape == (0, )
990993

991994
def test_reorder_levels(self):
992995
# this blows up

0 commit comments

Comments
 (0)