Skip to content

Commit 53eb999

Browse files
Nicholas Ver Halenjorisvandenbossche
Nicholas Ver Halen
authored andcommitted
BUG: to_numeric downcast = 'unsigned' would not un-sign a 0 value
closes pandas-dev#14504 closes pandas-dev#14401 (cherry picked from commit b5864b0)
1 parent 25782fa commit 53eb999

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

doc/source/whatsnew/v0.19.2.txt

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ Bug Fixes
3333

3434

3535
- Bug in ``pd.cut`` with negative values and a single bin (:issue:`14652`)
36+
- Bug in ``pd.to_numeric`` where a 0 was not unsigned on a ``downcast='unsigned'`` argument (:issue:`14401`)
3637

3738

3839

pandas/tools/tests/test_util.py

+37-1
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@
44
import nose
55

66
import numpy as np
7+
from numpy import iinfo
78

89
import pandas as pd
9-
from pandas import date_range, Index
10+
from pandas import (date_range, Index, _np_version_under1p9)
1011
import pandas.util.testing as tm
1112
from pandas.tools.util import cartesian_product, to_numeric
1213

@@ -401,6 +402,41 @@ def test_downcast(self):
401402
res = pd.to_numeric(data, downcast=downcast)
402403
tm.assert_numpy_array_equal(res, expected)
403404

405+
def test_downcast_limits(self):
406+
# Test the limits of each downcast. Bug: #14401.
407+
# Check to make sure numpy is new enough to run this test.
408+
if _np_version_under1p9:
409+
raise nose.SkipTest("Numpy version is under 1.9")
410+
411+
i = 'integer'
412+
u = 'unsigned'
413+
dtype_downcast_min_max = [
414+
('int8', i, [iinfo(np.int8).min, iinfo(np.int8).max]),
415+
('int16', i, [iinfo(np.int16).min, iinfo(np.int16).max]),
416+
('int32', i, [iinfo(np.int32).min, iinfo(np.int32).max]),
417+
('int64', i, [iinfo(np.int64).min, iinfo(np.int64).max]),
418+
('uint8', u, [iinfo(np.uint8).min, iinfo(np.uint8).max]),
419+
('uint16', u, [iinfo(np.uint16).min, iinfo(np.uint16).max]),
420+
('uint32', u, [iinfo(np.uint32).min, iinfo(np.uint32).max]),
421+
# Test will be skipped until there is more uint64 support.
422+
# ('uint64', u, [iinfo(uint64).min, iinfo(uint64).max]),
423+
('int16', i, [iinfo(np.int8).min, iinfo(np.int8).max + 1]),
424+
('int32', i, [iinfo(np.int16).min, iinfo(np.int16).max + 1]),
425+
('int64', i, [iinfo(np.int32).min, iinfo(np.int32).max + 1]),
426+
('int16', i, [iinfo(np.int8).min - 1, iinfo(np.int16).max]),
427+
('int32', i, [iinfo(np.int16).min - 1, iinfo(np.int32).max]),
428+
('int64', i, [iinfo(np.int32).min - 1, iinfo(np.int64).max]),
429+
('uint16', u, [iinfo(np.uint8).min, iinfo(np.uint8).max + 1]),
430+
('uint32', u, [iinfo(np.uint16).min, iinfo(np.uint16).max + 1]),
431+
# Test will be skipped until there is more uint64 support.
432+
# ('uint64', u, [iinfo(np.uint32).min, iinfo(np.uint32).max + 1]),
433+
]
434+
435+
for dtype, downcast, min_max in dtype_downcast_min_max:
436+
series = pd.to_numeric(pd.Series(min_max), downcast=downcast)
437+
tm.assert_equal(series.dtype, dtype)
438+
439+
404440
if __name__ == '__main__':
405441
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
406442
exit=False)

pandas/tools/util.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ def to_numeric(arg, errors='raise', downcast=None):
205205

206206
if downcast in ('integer', 'signed'):
207207
typecodes = np.typecodes['Integer']
208-
elif downcast == 'unsigned' and np.min(values) > 0:
208+
elif downcast == 'unsigned' and np.min(values) >= 0:
209209
typecodes = np.typecodes['UnsignedInteger']
210210
elif downcast == 'float':
211211
typecodes = np.typecodes['Float']

0 commit comments

Comments
 (0)