Skip to content

Commit 1bffe76

Browse files
committed
Change UInt64Index._na_value from 0 to np.nan
1 parent 509e03c commit 1bffe76

File tree

5 files changed

+55
-37
lines changed

5 files changed

+55
-37
lines changed

doc/source/whatsnew/v0.22.0.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ Bug Fixes
108108
Conversion
109109
^^^^^^^^^^
110110

111-
-
111+
- Bug in :class:`Index` constructor with `dtype='uint64'` where int-like floats were not coerced to :class:`UInt64Index` (:issue:`18400`)
112112
-
113113
-
114114

pandas/core/indexes/base.py

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None,
251251
# then coerce to integer.
252252
try:
253253
return cls._try_convert_to_int_index(
254-
data, copy, name)
254+
data, copy, name, dtype)
255255
except ValueError:
256256
pass
257257

@@ -307,7 +307,7 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None,
307307
if inferred == 'integer':
308308
try:
309309
return cls._try_convert_to_int_index(
310-
subarr, copy, name)
310+
subarr, copy, name, dtype)
311311
except ValueError:
312312
pass
313313

@@ -664,7 +664,7 @@ def ravel(self, order='C'):
664664

665665
# construction helpers
666666
@classmethod
667-
def _try_convert_to_int_index(cls, data, copy, name):
667+
def _try_convert_to_int_index(cls, data, copy, name, dtype):
668668
"""
669669
Attempt to convert an array of data into an integer index.
670670
@@ -685,12 +685,13 @@ def _try_convert_to_int_index(cls, data, copy, name):
685685
"""
686686

687687
from .numeric import Int64Index, UInt64Index
688-
try:
689-
res = data.astype('i8', copy=False)
690-
if (res == data).all():
691-
return Int64Index(res, copy=copy, name=name)
692-
except (OverflowError, TypeError, ValueError):
693-
pass
688+
if not is_unsigned_integer_dtype(dtype):
689+
try:
690+
res = data.astype('i8', copy=False)
691+
if (res == data).all():
692+
return Int64Index(res, copy=copy, name=name)
693+
except (OverflowError, TypeError, ValueError):
694+
pass
694695

695696
# Conversion to int64 failed (possibly due to
696697
# overflow), so let's try now with uint64.

pandas/core/indexes/numeric.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,6 @@ class UInt64Index(NumericIndex):
216216
_inner_indexer = libjoin.inner_join_indexer_uint64
217217
_outer_indexer = libjoin.outer_join_indexer_uint64
218218
_can_hold_na = False
219-
_na_value = 0
220219
_engine_type = libindex.UInt64Engine
221220
_default_dtype = np.uint64
222221

pandas/tests/indexes/test_base.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
import numpy as np
1515

1616
from pandas import (period_range, date_range, Series,
17-
DataFrame, Float64Index, Int64Index,
17+
DataFrame, Float64Index, Int64Index, UInt64Index,
1818
CategoricalIndex, DatetimeIndex, TimedeltaIndex,
1919
PeriodIndex, isna)
2020
from pandas.core.index import _get_combined_index, _ensure_index_from_sequences
@@ -201,6 +201,25 @@ def __array__(self, dtype=None):
201201
result = pd.Index(ArrayLike(array))
202202
tm.assert_index_equal(result, expected)
203203

204+
def test_constructor_int_dtype_float(self):
205+
# GH 18400
206+
data = [0., 1., 2., 3.]
207+
208+
expected = Int64Index([0, 1, 2, 3])
209+
result = Index(data, dtype='int64')
210+
tm.assert_index_equal(result, expected)
211+
212+
expected = UInt64Index([0, 1, 2, 3])
213+
result = Index(data, dtype='uint64')
214+
tm.assert_index_equal(result, expected)
215+
216+
# fall back to Float64Index
217+
data = [0.0, 1.1, 2.2, 3.3]
218+
expected = Float64Index(data)
219+
for dtype in ('int64', 'uint64'):
220+
result = Index(data, dtype=dtype)
221+
tm.assert_index_equal(result, expected)
222+
204223
def test_constructor_int_dtype_nan(self):
205224
# see gh-15187
206225
data = [np.nan]

pandas/tests/indexes/test_numeric.py

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -658,6 +658,30 @@ def test_ufunc_coercions(self):
658658
exp = Float64Index([0.5, 1., 1.5, 2., 2.5], name='x')
659659
tm.assert_index_equal(result, exp)
660660

661+
def test_where(self):
662+
i = self.create_index()
663+
result = i.where(notna(i))
664+
expected = i
665+
tm.assert_index_equal(result, expected)
666+
667+
_nan = i._na_value
668+
cond = [False] + [True] * len(i[1:])
669+
expected = Float64Index([_nan] + i[1:].tolist())
670+
result = i.where(cond)
671+
tm.assert_index_equal(result, expected)
672+
673+
def test_where_array_like(self):
674+
i = self.create_index()
675+
676+
_nan = i._na_value
677+
cond = [False] + [True] * (len(i) - 1)
678+
klasses = [list, tuple, np.array, pd.Series]
679+
expected = Float64Index([_nan] + i[1:].tolist())
680+
681+
for klass in klasses:
682+
result = i.where(klass(cond))
683+
tm.assert_index_equal(result, expected)
684+
661685

662686
class TestInt64Index(NumericInt):
663687
_dtype = 'int64'
@@ -726,31 +750,6 @@ def test_coerce_list(self):
726750
arr = Index([1, 2, 3, 4], dtype=object)
727751
assert isinstance(arr, Index)
728752

729-
def test_where(self):
730-
i = self.create_index()
731-
result = i.where(notna(i))
732-
expected = i
733-
tm.assert_index_equal(result, expected)
734-
735-
_nan = i._na_value
736-
cond = [False] + [True] * len(i[1:])
737-
expected = pd.Index([_nan] + i[1:].tolist())
738-
739-
result = i.where(cond)
740-
tm.assert_index_equal(result, expected)
741-
742-
def test_where_array_like(self):
743-
i = self.create_index()
744-
745-
_nan = i._na_value
746-
cond = [False] + [True] * (len(i) - 1)
747-
klasses = [list, tuple, np.array, pd.Series]
748-
expected = pd.Index([_nan] + i[1:].tolist())
749-
750-
for klass in klasses:
751-
result = i.where(klass(cond))
752-
tm.assert_index_equal(result, expected)
753-
754753
def test_get_indexer(self):
755754
target = Int64Index(np.arange(10))
756755
indexer = self.index.get_indexer(target)

0 commit comments

Comments
 (0)