Skip to content

Commit 92f10f3

Browse files
committed
BUG: Convert uint64 in maybe_convert_objects
Adds handling for uint64 objects during conversion. When negative numbers and uint64 are detected, we then convert the result to object. Picks up where gh-4845 left off. Closes gh-4471.
1 parent f1cfe5b commit 92f10f3

File tree

3 files changed

+41
-5
lines changed

3 files changed

+41
-5
lines changed

doc/source/whatsnew/v0.20.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -251,3 +251,4 @@ Bug Fixes
251251

252252

253253
- Require at least 0.23 version of cython to avoid problems with character encodings (:issue:`14699`)
254+
- Bug in ``lib.maybe_convert_objects()`` in which unsigned 64-bit integers were not being properly converted (:issue:`4471`)

pandas/src/inference.pyx

+25-5
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,7 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
722722
ndarray[float64_t] floats
723723
ndarray[complex128_t] complexes
724724
ndarray[int64_t] ints
725+
ndarray[uint64_t] uints
725726
ndarray[uint8_t] bools
726727
ndarray[int64_t] idatetimes
727728
ndarray[int64_t] itimedeltas
@@ -731,6 +732,8 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
731732
bint seen_datetimetz = 0
732733
bint seen_timedelta = 0
733734
bint seen_int = 0
735+
bint seen_uint = 0
736+
bint seen_sint = 0
734737
bint seen_bool = 0
735738
bint seen_object = 0
736739
bint seen_null = 0
@@ -743,6 +746,7 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
743746
floats = np.empty(n, dtype='f8')
744747
complexes = np.empty(n, dtype='c16')
745748
ints = np.empty(n, dtype='i8')
749+
uints = np.empty(n, dtype='u8')
746750
bools = np.empty(n, dtype=np.uint8)
747751

748752
if convert_datetime:
@@ -798,11 +802,21 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
798802
floats[i] = <float64_t> val
799803
complexes[i] = <double complex> val
800804
if not seen_null:
801-
try:
802-
ints[i] = val
803-
except OverflowError:
805+
seen_uint = seen_uint or (val > np.iinfo(np.int64).max)
806+
seen_sint = seen_sint or (val < 0)
807+
808+
if seen_uint and seen_sint:
804809
seen_object = 1
805810
break
811+
812+
if seen_uint:
813+
uints[i] = val
814+
elif seen_sint:
815+
ints[i] = val
816+
else:
817+
uints[i] = val
818+
ints[i] = val
819+
806820
elif util.is_complex_object(val):
807821
complexes[i] = val
808822
seen_complex = 1
@@ -865,7 +879,10 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
865879
elif seen_float:
866880
return floats
867881
elif seen_int:
868-
return ints
882+
if seen_uint:
883+
return uints
884+
else:
885+
return ints
869886
elif (not seen_datetime and not seen_numeric
870887
and not seen_timedelta):
871888
return bools.view(np.bool_)
@@ -896,7 +913,10 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
896913
if not seen_int:
897914
return floats
898915
elif seen_int:
899-
return ints
916+
if seen_uint:
917+
return uints
918+
else:
919+
return ints
900920
elif (not seen_datetime and not seen_numeric
901921
and not seen_timedelta):
902922
return bools.view(np.bool_)

pandas/tests/test_lib.py

+15
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,21 @@ def test_empty_like(self):
234234
self._check_behavior(arr, expected)
235235

236236

237+
def test_maybe_convert_objects_uint64():
238+
# see gh-4471
239+
arr = np.array([2**63], dtype=object)
240+
exp = np.array([2**63], dtype=np.uint64)
241+
tm.assert_numpy_array_equal(lib.maybe_convert_objects(arr), exp)
242+
243+
arr = np.array([2, -1], dtype=object)
244+
exp = np.array([2, -1], dtype=np.int64)
245+
tm.assert_numpy_array_equal(lib.maybe_convert_objects(arr), exp)
246+
247+
arr = np.array([2**63, -1], dtype=object)
248+
exp = np.array([2**63, -1], dtype=object)
249+
tm.assert_numpy_array_equal(lib.maybe_convert_objects(arr), exp)
250+
251+
237252
if __name__ == '__main__':
238253
import nose
239254

0 commit comments

Comments
 (0)