Skip to content

Commit 37086a0

Browse files
toobazjreback
authored andcommitted
BUG: get_level_values() on int level upcasts to Float64Index if needed (#17930)
closes #17924
1 parent b8b108c commit 37086a0

File tree

3 files changed

+33
-9
lines changed

3 files changed

+33
-9
lines changed

doc/source/whatsnew/v0.22.0.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ Other API Changes
189189
- :func:`pandas.DataFrame.merge` no longer casts a ``float`` column to ``object`` when merging on ``int`` and ``float`` columns (:issue:`16572`)
190190
- The default NA value for :class:`UInt64Index` has changed from 0 to ``NaN``, which impacts methods that mask with NA, such as ``UInt64Index.where()`` (:issue:`18398`)
191191
- Refactored ``setup.py`` to use ``find_packages`` instead of explicitly listing out all subpackages (:issue:`18535`)
192-
- Rearranged the order of keyword arguments in :func:`read_excel()` to align with :func:`read_csv()` (:pr:`16672`)
192+
- Rearranged the order of keyword arguments in :func:`read_excel()` to align with :func:`read_csv()` (:issue:`16672`)
193193
- :func:`pandas.merge` now raises a ``ValueError`` when trying to merge on incompatible data types (:issue:`9780`)
194194
- :func:`wide_to_long` previously kept numeric-like suffixes as ``object`` dtype. Now they are cast to numeric if possible (:issue:`17627`)
195195

@@ -266,6 +266,7 @@ Indexing
266266

267267
- Bug in :func:`Series.truncate` which raises ``TypeError`` with a monotonic ``PeriodIndex`` (:issue:`17717`)
268268
- Bug in :func:`DataFrame.groupby` where tuples were interpreted as lists of keys rather than as keys (:issue:`17979`, :issue:`18249`)
269+
- Bug in :func:`MultiIndex.get_level_values` which would return an invalid index on level of ints with missing values (:issue:`17924`)
269270
- Bug in :func:`MultiIndex.remove_unused_levels` which would fill nan values (:issue:`18417`)
270271
- Bug in :func:`MultiIndex.from_tuples`` which would fail to take zipped tuples in python3 (:issue:`18434`)
271272
- Bug in :class:`Index` construction from list of mixed type tuples (:issue:`18505`)

pandas/core/indexes/numeric.py

+13-3
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ def _maybe_cast_slice_bound(self, label, side, kind):
6262
# we will try to coerce to integers
6363
return self._maybe_cast_indexer(label)
6464

65+
@Appender(_index_shared_docs['_shallow_copy'])
66+
def _shallow_copy(self, values=None, **kwargs):
67+
if values is not None and not self._can_hold_na:
68+
# Ensure we are not returning an Int64Index with float data:
69+
return self._shallow_copy_with_infer(values=values, **kwargs)
70+
return (super(NumericIndex, self)._shallow_copy(values=values,
71+
**kwargs))
72+
6573
def _convert_for_op(self, value):
6674
""" Convert value to be insertable to ndarray """
6775

@@ -395,9 +403,11 @@ def __contains__(self, other):
395403
try:
396404
return len(other) <= 1 and ibase._try_get_item(other) in self
397405
except TypeError:
398-
return False
399-
except:
400-
return False
406+
pass
407+
except TypeError:
408+
pass
409+
410+
return False
401411

402412
@Appender(_index_shared_docs['get_loc'])
403413
def get_loc(self, key, method=None, tolerance=None):

pandas/tests/indexes/test_multi.py

+18-5
Original file line numberDiff line numberDiff line change
@@ -997,8 +997,8 @@ def test_get_level_values(self):
997997
exp = CategoricalIndex([1, 2, 3, 1, 2, 3])
998998
tm.assert_index_equal(index.get_level_values(1), exp)
999999

1000-
@pytest.mark.xfail(reason='GH 17924 (returns Int64Index with float data)')
10011000
def test_get_level_values_int_with_na(self):
1001+
# GH 17924
10021002
arrays = [['a', 'b', 'b'], [1, np.nan, 2]]
10031003
index = pd.MultiIndex.from_arrays(arrays)
10041004
result = index.get_level_values(1)
@@ -1024,14 +1024,27 @@ def test_get_level_values_na(self):
10241024

10251025
arrays = [['a', 'b', 'b'], pd.DatetimeIndex([0, 1, pd.NaT])]
10261026
index = pd.MultiIndex.from_arrays(arrays)
1027-
values = index.get_level_values(1)
1027+
result = index.get_level_values(1)
10281028
expected = pd.DatetimeIndex([0, 1, pd.NaT])
1029-
tm.assert_index_equal(values, expected)
1029+
tm.assert_index_equal(result, expected)
10301030

10311031
arrays = [[], []]
10321032
index = pd.MultiIndex.from_arrays(arrays)
1033-
values = index.get_level_values(0)
1034-
assert values.shape == (0, )
1033+
result = index.get_level_values(0)
1034+
expected = pd.Index([], dtype=object)
1035+
tm.assert_index_equal(result, expected)
1036+
1037+
def test_get_level_values_all_na(self):
1038+
# GH 17924 when level entirely consists of nan
1039+
arrays = [[np.nan, np.nan, np.nan], ['a', np.nan, 1]]
1040+
index = pd.MultiIndex.from_arrays(arrays)
1041+
result = index.get_level_values(0)
1042+
expected = pd.Index([np.nan, np.nan, np.nan], dtype=np.float64)
1043+
tm.assert_index_equal(result, expected)
1044+
1045+
result = index.get_level_values(1)
1046+
expected = pd.Index(['a', np.nan, 1], dtype=object)
1047+
tm.assert_index_equal(result, expected)
10351048

10361049
def test_reorder_levels(self):
10371050
# this blows up

0 commit comments

Comments
 (0)