From a594847dd7f930612ade08060b4c938d947f8876 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 02:10:22 -0500 Subject: [PATCH 01/18] tests --- pandas/tests/tools/test_to_numeric.py | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index f89958f7723ef..db947aafc5a07 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -725,3 +725,19 @@ def test_to_numeric_from_nullable_string(values, expected): s = Series(values, dtype="string") result = to_numeric(s) tm.assert_series_equal(result, expected) + + +@pytest.mark.parametrize( + "data, input_dtype, downcast, expected_dtype", + ( + ([1, 1], "Int64", "integer", "Int8"), + ([450, 300], "Int64", "integer", "Int16"), + ([1, 1], "Float64", "float", "Float32"), + ([1, 1], "Float64", "integer", "Int8"), + ), +) +def test_downcast_nullable_numeric(data, input_dtype, downcast, expected_dtype): + arr = pd.array(data, dtype=input_dtype) + result = pd.to_numeric(arr, downcast=downcast) + expected = pd.array(data, dtype=expected_dtype) + tm.assert_extension_array_equal(result, expected) From a1bb9fc065e0654b33cc6d9e520bae6c62d977d2 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 02:10:35 -0500 Subject: [PATCH 02/18] add NumericArray path in to_numeric --- pandas/core/tools/numeric.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 08cdfde7df58d..161c8adb88bdb 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -7,6 +7,9 @@ ensure_object, is_datetime_or_timedelta_dtype, is_decimal, + is_extension_array_dtype, + is_float_dtype, + is_integer_dtype, is_number, is_numeric_dtype, is_scalar, @@ -15,6 +18,8 @@ from pandas.core.dtypes.generic import ABCIndex, ABCSeries import pandas as pd +from pandas.core.arrays.numeric import NumericArray +from pandas.core.construction import extract_array def to_numeric(arg, errors="raise", downcast=None): @@ -118,10 +123,14 @@ def to_numeric(arg, errors="raise", downcast=None): is_series = False is_index = False is_scalars = False + is_numeric_extension_dtype = False if isinstance(arg, ABCSeries): is_series = True values = arg.values + if is_extension_array_dtype(arg) and isinstance(values, NumericArray): + is_numeric_extension_dtype = True + values = extract_array(arg) elif isinstance(arg, ABCIndex): is_index = True if needs_i8_conversion(arg.dtype): @@ -142,6 +151,14 @@ def to_numeric(arg, errors="raise", downcast=None): else: values = arg + if is_numeric_extension_dtype or ( + is_extension_array_dtype(arg) and isinstance(values, NumericArray) + ): + is_numeric_extension_dtype = True + mask = values._mask + values = values.to_numpy() + values[mask] = 0 + values_dtype = getattr(values, "dtype", None) if is_numeric_dtype(values_dtype): pass @@ -188,6 +205,16 @@ def to_numeric(arg, errors="raise", downcast=None): if values.dtype == dtype: break + if is_numeric_extension_dtype: + if is_integer_dtype(values): + from pandas.core.arrays import IntegerArray + + values = IntegerArray(values, mask) + elif is_float_dtype(values): + from pandas.core.arrays import FloatingArray + + values = FloatingArray(values, mask) + if is_series: return arg._constructor(values, index=arg.index, name=arg.name) elif is_index: From dbba7b4c749d321c7b22a127b6efc4efb7673bd7 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 02:18:13 -0500 Subject: [PATCH 03/18] replace to_numpy use with _data --- pandas/core/tools/numeric.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 161c8adb88bdb..efa2c1165f789 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -155,9 +155,7 @@ def to_numeric(arg, errors="raise", downcast=None): is_extension_array_dtype(arg) and isinstance(values, NumericArray) ): is_numeric_extension_dtype = True - mask = values._mask - values = values.to_numpy() - values[mask] = 0 + mask, values = values._mask, values._data values_dtype = getattr(values, "dtype", None) if is_numeric_dtype(values_dtype): From ddb71cbc7c1a6b3cd22f3ee2924d80dce5a1d58c Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 11:24:02 -0500 Subject: [PATCH 04/18] review comment --- pandas/core/tools/numeric.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index efa2c1165f789..2999f1fa3178c 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -19,7 +19,6 @@ import pandas as pd from pandas.core.arrays.numeric import NumericArray -from pandas.core.construction import extract_array def to_numeric(arg, errors="raise", downcast=None): @@ -128,9 +127,6 @@ def to_numeric(arg, errors="raise", downcast=None): if isinstance(arg, ABCSeries): is_series = True values = arg.values - if is_extension_array_dtype(arg) and isinstance(values, NumericArray): - is_numeric_extension_dtype = True - values = extract_array(arg) elif isinstance(arg, ABCIndex): is_index = True if needs_i8_conversion(arg.dtype): @@ -151,9 +147,7 @@ def to_numeric(arg, errors="raise", downcast=None): else: values = arg - if is_numeric_extension_dtype or ( - is_extension_array_dtype(arg) and isinstance(values, NumericArray) - ): + if is_extension_array_dtype(arg) and isinstance(values, NumericArray): is_numeric_extension_dtype = True mask, values = values._mask, values._data From 323cfdc5f1353b649067acdd8bfd1312bcc2ffc7 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 11:59:31 -0500 Subject: [PATCH 05/18] more testcases --- pandas/tests/tools/test_to_numeric.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index db947aafc5a07..61046fd3526b2 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -731,7 +731,16 @@ def test_to_numeric_from_nullable_string(values, expected): "data, input_dtype, downcast, expected_dtype", ( ([1, 1], "Int64", "integer", "Int8"), + ([1, pd.NA], "Int64", "integer", "Int8"), ([450, 300], "Int64", "integer", "Int16"), + ([1, 1], "Int64", "signed", "Int8"), + ([1, pd.NA], "Int64", "signed", "Int8"), + ([450, -300], "Int64", "signed", "Int16"), + ([1, 1], "Int64", "unsigned", "UInt8"), + ([1, pd.NA], "Int64", "unsigned", "UInt8"), + ([450, -300], "Int64", "unsigned", "Int64"), + ([-1, -1], "Int32", "unsigned", "Int32"), + ([1, 1], "Float64", "float", "Float32"), ([1, 1], "Float64", "float", "Float32"), ([1, 1], "Float64", "integer", "Int8"), ), From 337589a838f1d8bd9d231514fb18696952e8b026 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 12:18:59 -0500 Subject: [PATCH 06/18] whatsnew --- doc/source/whatsnew/v1.3.0.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/source/whatsnew/v1.3.0.rst b/doc/source/whatsnew/v1.3.0.rst index b41931a803053..6f22af4992ca0 100644 --- a/doc/source/whatsnew/v1.3.0.rst +++ b/doc/source/whatsnew/v1.3.0.rst @@ -50,6 +50,7 @@ Other enhancements - Improved consistency of error message when passing an invalid ``win_type`` argument in :class:`Window` (:issue:`15969`) - :func:`pandas.read_sql_query` now accepts a ``dtype`` argument to cast the columnar data from the SQL database based on user input (:issue:`10285`) - Improved integer type mapping from pandas to SQLAlchemy when using :meth:`DataFrame.to_sql` (:issue:`35076`) +- :func:`to_numeric` now supports downcasting of nullable ``ExtensionDtype`` objects (:issue:`33013`) .. --------------------------------------------------------------------------- From 4e8761add6b608171b3216f8dc84ff52b741afc6 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 13:50:11 -0500 Subject: [PATCH 07/18] review comments --- pandas/core/tools/numeric.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 2999f1fa3178c..c534a61755da9 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -7,7 +7,6 @@ ensure_object, is_datetime_or_timedelta_dtype, is_decimal, - is_extension_array_dtype, is_float_dtype, is_integer_dtype, is_number, @@ -122,7 +121,6 @@ def to_numeric(arg, errors="raise", downcast=None): is_series = False is_index = False is_scalars = False - is_numeric_extension_dtype = False if isinstance(arg, ABCSeries): is_series = True @@ -147,9 +145,11 @@ def to_numeric(arg, errors="raise", downcast=None): else: values = arg - if is_extension_array_dtype(arg) and isinstance(values, NumericArray): - is_numeric_extension_dtype = True - mask, values = values._mask, values._data + if isinstance(values, NumericArray): + mask = values._mask + values = values._data[~mask] + else: + mask = None values_dtype = getattr(values, "dtype", None) if is_numeric_dtype(values_dtype): @@ -197,7 +197,11 @@ def to_numeric(arg, errors="raise", downcast=None): if values.dtype == dtype: break - if is_numeric_extension_dtype: + if mask is not None: + buf = np.zeros(mask.shape, dtype=values.dtype) + buf[~mask] = values + values = buf + if is_integer_dtype(values): from pandas.core.arrays import IntegerArray From e2b4cbb8658dfb23bd93e40e242b17827ea98ebd Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 13:59:01 -0500 Subject: [PATCH 08/18] cleanup --- pandas/core/tools/numeric.py | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index c534a61755da9..49c25fda8db82 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -198,18 +198,17 @@ def to_numeric(arg, errors="raise", downcast=None): break if mask is not None: - buf = np.zeros(mask.shape, dtype=values.dtype) - buf[~mask] = values - values = buf + data = np.zeros(mask.shape, dtype=values.dtype) + data[~mask] = values - if is_integer_dtype(values): + if is_integer_dtype(data): from pandas.core.arrays import IntegerArray - values = IntegerArray(values, mask) - elif is_float_dtype(values): + values = IntegerArray(data, mask) + elif is_float_dtype(data): from pandas.core.arrays import FloatingArray - values = FloatingArray(values, mask) + values = FloatingArray(data, mask) if is_series: return arg._constructor(values, index=arg.index, name=arg.name) From 23c4ae6ad217f48baf55141f3eb037bfe3b944e7 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 14:05:00 -0500 Subject: [PATCH 09/18] review comments (tests) --- pandas/tests/tools/test_to_numeric.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index 61046fd3526b2..8afd13470c7cc 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -731,12 +731,15 @@ def test_to_numeric_from_nullable_string(values, expected): "data, input_dtype, downcast, expected_dtype", ( ([1, 1], "Int64", "integer", "Int8"), + ([1.0, 1.0], "Float64", "integer", "Int8"), ([1, pd.NA], "Int64", "integer", "Int8"), ([450, 300], "Int64", "integer", "Int16"), ([1, 1], "Int64", "signed", "Int8"), + ([1.0, 1.0], "Float32", "signed", "Int8"), ([1, pd.NA], "Int64", "signed", "Int8"), ([450, -300], "Int64", "signed", "Int16"), ([1, 1], "Int64", "unsigned", "UInt8"), + ([1.0, 1.0], "Float32", "unsigned", "UInt8"), ([1, pd.NA], "Int64", "unsigned", "UInt8"), ([450, -300], "Int64", "unsigned", "Int64"), ([-1, -1], "Int32", "unsigned", "Int32"), From e140b7a9366b7d9ee2440f1ef5bf3cb82bd2faad Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 14:09:10 -0500 Subject: [PATCH 10/18] more tests --- pandas/tests/tools/test_to_numeric.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index 8afd13470c7cc..903b31c9a385d 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -732,19 +732,22 @@ def test_to_numeric_from_nullable_string(values, expected): ( ([1, 1], "Int64", "integer", "Int8"), ([1.0, 1.0], "Float64", "integer", "Int8"), + ([1.0, 1.1], "Float64", "integer", "Float64"), ([1, pd.NA], "Int64", "integer", "Int8"), ([450, 300], "Int64", "integer", "Int16"), ([1, 1], "Int64", "signed", "Int8"), ([1.0, 1.0], "Float32", "signed", "Int8"), + ([1.0, 1.1], "Float64", "signed", "Float64"), ([1, pd.NA], "Int64", "signed", "Int8"), ([450, -300], "Int64", "signed", "Int16"), ([1, 1], "Int64", "unsigned", "UInt8"), ([1.0, 1.0], "Float32", "unsigned", "UInt8"), + ([1.0, 1.1], "Float64", "unsigned", "Float64"), ([1, pd.NA], "Int64", "unsigned", "UInt8"), ([450, -300], "Int64", "unsigned", "Int64"), ([-1, -1], "Int32", "unsigned", "Int32"), ([1, 1], "Float64", "float", "Float32"), - ([1, 1], "Float64", "float", "Float32"), + ([1, 1.1], "Float64", "float", "Float32"), ([1, 1], "Float64", "integer", "Int8"), ), ) From f583a10a84f3a6aa0377587c3e1893232eb97351 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska <48889395+arw2019@users.noreply.github.com> Date: Mon, 28 Dec 2020 14:16:45 -0500 Subject: [PATCH 11/18] de-duplicate testcae Co-authored-by: Joris Van den Bossche --- pandas/tests/tools/test_to_numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index 903b31c9a385d..d45d273dc9488 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -731,7 +731,7 @@ def test_to_numeric_from_nullable_string(values, expected): "data, input_dtype, downcast, expected_dtype", ( ([1, 1], "Int64", "integer", "Int8"), - ([1.0, 1.0], "Float64", "integer", "Int8"), + ([1.0, pd.NA], "Float64", "integer", "Int8"), ([1.0, 1.1], "Float64", "integer", "Float64"), ([1, pd.NA], "Int64", "integer", "Int8"), ([450, 300], "Int64", "integer", "Int16"), From a6cb1527fc394ca48ed273d0bcd7380115e45521 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Mon, 28 Dec 2020 14:30:42 -0500 Subject: [PATCH 12/18] more cleanup --- pandas/core/tools/numeric.py | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 49c25fda8db82..a7a2474097771 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -7,7 +7,6 @@ ensure_object, is_datetime_or_timedelta_dtype, is_decimal, - is_float_dtype, is_integer_dtype, is_number, is_numeric_dtype, @@ -201,14 +200,10 @@ def to_numeric(arg, errors="raise", downcast=None): data = np.zeros(mask.shape, dtype=values.dtype) data[~mask] = values - if is_integer_dtype(data): - from pandas.core.arrays import IntegerArray + from pandas.core.arrays import FloatingArray, IntegerArray - values = IntegerArray(data, mask) - elif is_float_dtype(data): - from pandas.core.arrays import FloatingArray - - values = FloatingArray(data, mask) + klass = IntegerArray if is_integer_dtype(data.dtype) else FloatingArray + values = klass(data, mask) if is_series: return arg._constructor(values, index=arg.index, name=arg.name) From d707a6174456906cb95248b2cdd3740c8bdf5236 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Wed, 30 Dec 2020 01:01:15 -0500 Subject: [PATCH 13/18] review: code comments --- pandas/core/tools/numeric.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index a7a2474097771..1e94e7b0b6d85 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -144,6 +144,8 @@ def to_numeric(arg, errors="raise", downcast=None): else: values = arg + # GH33013: for IntegerArray & FloatingArray extract non-null values for casting + # save mask to reconstruct the full array after casting if isinstance(values, NumericArray): mask = values._mask values = values._data[~mask] @@ -196,6 +198,7 @@ def to_numeric(arg, errors="raise", downcast=None): if values.dtype == dtype: break + # GH33013: for IntegerArray & FloatingArray need to reconstruct full array if mask is not None: data = np.zeros(mask.shape, dtype=values.dtype) data[~mask] = values From 6b2c39fe65e04bc9c64381ffd309cd29df15a9cc Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Wed, 30 Dec 2020 01:02:31 -0500 Subject: [PATCH 14/18] review: code comments --- pandas/core/tools/numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 1e94e7b0b6d85..4ca0facf3487a 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -198,7 +198,7 @@ def to_numeric(arg, errors="raise", downcast=None): if values.dtype == dtype: break - # GH33013: for IntegerArray & FloatingArray need to reconstruct full array + # GH33013: for IntegerArray & FloatingArray need to reconstruct masked array if mask is not None: data = np.zeros(mask.shape, dtype=values.dtype) data[~mask] = values From fda4ba114b0eb98a5f3e98b8ba6606cbf8f85710 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Wed, 30 Dec 2020 01:07:36 -0500 Subject: [PATCH 15/18] review: update docstring --- pandas/core/tools/numeric.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 4ca0facf3487a..7870119bd0fcf 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -110,6 +110,21 @@ def to_numeric(arg, errors="raise", downcast=None): 2 2.0 3 -3.0 dtype: float64 + + Downcasting of ``ExtensionDtype`` is supported: + + >>> s = pd.Series([1, 2, 3], dtype="Int64") + >>> pd.to_numeric(s, downcast="integer") + 0 1 + 1 2 + 2 3 + dtype: Int8 + >>> s = pd.Series([1.0, 2.1, 3.0], dtype="Float64") + >>> pd.to_numeric(s, downcast="float") + 0 1.0 + 1 2.1 + 2 3.0 + dtype: Float32 """ if downcast not in (None, "integer", "signed", "unsigned", "float"): raise ValueError("invalid downcasting method provided") From 1a231187395caa42967ed15153eda69de057ee5b Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Wed, 30 Dec 2020 01:09:22 -0500 Subject: [PATCH 16/18] review: reorder test parameters --- pandas/tests/tools/test_to_numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index d45d273dc9488..b6f67df01157e 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -735,6 +735,7 @@ def test_to_numeric_from_nullable_string(values, expected): ([1.0, 1.1], "Float64", "integer", "Float64"), ([1, pd.NA], "Int64", "integer", "Int8"), ([450, 300], "Int64", "integer", "Int16"), + ([1, 1], "Float64", "integer", "Int8"), ([1, 1], "Int64", "signed", "Int8"), ([1.0, 1.0], "Float32", "signed", "Int8"), ([1.0, 1.1], "Float64", "signed", "Float64"), @@ -748,7 +749,6 @@ def test_to_numeric_from_nullable_string(values, expected): ([-1, -1], "Int32", "unsigned", "Int32"), ([1, 1], "Float64", "float", "Float32"), ([1, 1.1], "Float64", "float", "Float32"), - ([1, 1], "Float64", "integer", "Int8"), ), ) def test_downcast_nullable_numeric(data, input_dtype, downcast, expected_dtype): From 1015b075104aff4b281ecafe2d3fdc7a4f0604e5 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska Date: Wed, 30 Dec 2020 01:36:26 -0500 Subject: [PATCH 17/18] review: add testcases --- pandas/tests/tools/test_to_numeric.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index b6f67df01157e..80446e464985c 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -736,11 +736,19 @@ def test_to_numeric_from_nullable_string(values, expected): ([1, pd.NA], "Int64", "integer", "Int8"), ([450, 300], "Int64", "integer", "Int16"), ([1, 1], "Float64", "integer", "Int8"), + ([np.iinfo(np.int64).max - 1, 1], "Int64", "integer", "Int64"), ([1, 1], "Int64", "signed", "Int8"), ([1.0, 1.0], "Float32", "signed", "Int8"), ([1.0, 1.1], "Float64", "signed", "Float64"), ([1, pd.NA], "Int64", "signed", "Int8"), ([450, -300], "Int64", "signed", "Int16"), + pytest.param( + [np.iinfo(np.uint64).max - 1, 1], + "UInt64", + "signed", + "UInt64", + marks=pytest.mark.xfail(reason="GH38798"), + ), ([1, 1], "Int64", "unsigned", "UInt8"), ([1.0, 1.0], "Float32", "unsigned", "UInt8"), ([1.0, 1.1], "Float64", "unsigned", "Float64"), From 56747da00609dff1b48a5d1ab04bf0bb468392a9 Mon Sep 17 00:00:00 2001 From: Andrew Wieteska <48889395+arw2019@users.noreply.github.com> Date: Wed, 30 Dec 2020 02:27:04 -0500 Subject: [PATCH 18/18] Update pandas/core/tools/numeric.py Co-authored-by: Joris Van den Bossche --- pandas/core/tools/numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 7870119bd0fcf..1389aba9525d3 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -111,7 +111,7 @@ def to_numeric(arg, errors="raise", downcast=None): 3 -3.0 dtype: float64 - Downcasting of ``ExtensionDtype`` is supported: + Downcasting of nullable integer and floating dtypes is supported: >>> s = pd.Series([1, 2, 3], dtype="Int64") >>> pd.to_numeric(s, downcast="integer")