From 4a8fbc8e1f4b62357dc2aa248ca80a8636a604f6 Mon Sep 17 00:00:00 2001 From: navaneethan2503 Date: Mon, 30 Aug 2021 02:07:43 +0530 Subject: [PATCH 1/4] modified changes for datetime and NaT Objects Behavior --- pandas/core/tools/numeric.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 7d2bb75934c33..a9e5ce8559720 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -175,7 +175,10 @@ def to_numeric(arg, errors="raise", downcast=None): if is_numeric_dtype(values_dtype): pass elif is_datetime_or_timedelta_dtype(values_dtype): - values = values.view(np.int64) + if pd.isnull(arg.values): + values = np.nan + else: + values = pd.to_datetime(values).strftime("%Y%m%d").astype(np.int64) else: values = ensure_object(values) coerce_numeric = errors not in ("ignore", "raise") @@ -236,7 +239,5 @@ def to_numeric(arg, errors="raise", downcast=None): # because we want to coerce to numeric if possible, # do not use _shallow_copy return pd.Index(values, name=arg.name) - elif is_scalars: - return values[0] else: - return values + return values[0] From 2e082a1e853528d69e6f01afafd975f6e3097407 Mon Sep 17 00:00:00 2001 From: navaneethan2503 Date: Mon, 30 Aug 2021 16:36:25 +0530 Subject: [PATCH 2/4] Scalar and series argument of datatime datatype and NaT Behaviour solved --- pandas/core/tools/numeric.py | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index a9e5ce8559720..cf8f4fee62a07 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -130,6 +130,19 @@ def to_numeric(arg, errors="raise", downcast=None): 1 2.1 2 3.0 dtype: Float32 + + Datetime dTypes is supported + + >>> s = pd.to_numeric(datetime(2021, 8, 22), errors="coerce") + 0 20210822 + dtype: Int64 + >>> s = pd.to_numeric(pd.NaT, errors="coerce") + nan + >>> s = pd.to_numeric(pd.Series(datetime(2021, 8, 22)), errors="coerce") + 0 20210822 + dtype: Int64 + >>> s = pd.to_numeric(pd.Series(pd.NaT), errors="coerce") + NaN """ if downcast not in (None, "integer", "signed", "unsigned", "float"): raise ValueError("invalid downcasting method provided") @@ -157,6 +170,11 @@ def to_numeric(arg, errors="raise", downcast=None): return float(arg) if is_number(arg): return arg + if isinstance(arg , datetime): + if pd.isnull(arg): + return np.NaN + else: + return int(pd.to_datetime(arg).strftime("%Y%m%d")) is_scalars = True values = np.array([arg], dtype="O") elif getattr(arg, "ndim", 1) > 1: @@ -175,10 +193,7 @@ def to_numeric(arg, errors="raise", downcast=None): if is_numeric_dtype(values_dtype): pass elif is_datetime_or_timedelta_dtype(values_dtype): - if pd.isnull(arg.values): - values = np.nan - else: - values = pd.to_datetime(values).strftime("%Y%m%d").astype(np.int64) + else: values = ensure_object(values) coerce_numeric = errors not in ("ignore", "raise") @@ -239,5 +254,7 @@ def to_numeric(arg, errors="raise", downcast=None): # because we want to coerce to numeric if possible, # do not use _shallow_copy return pd.Index(values, name=arg.name) - else: + elif is_scalars: return values[0] + else: + return values From 0db02650b4dc796be230181f169365311a87e563 Mon Sep 17 00:00:00 2001 From: navaneethan2503 Date: Tue, 31 Aug 2021 16:58:13 +0530 Subject: [PATCH 3/4] added test and release notes --- doc/source/whatsnew/v1.4.0.rst | 2 +- pandas/core/tools/numeric.py | 13 ------------- pandas/tests/tools/test_to_numeric.py | 26 ++++++++++++++++++++++++++ 3 files changed, 27 insertions(+), 14 deletions(-) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 450ecc85c725b..9224dd41d5e9c 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -267,7 +267,7 @@ Datetimelike ^^^^^^^^^^^^ - Bug in :class:`DataFrame` constructor unnecessarily copying non-datetimelike 2D object arrays (:issue:`39272`) - :func:`to_datetime` would silently swap ``MM/DD/YYYY`` and ``DD/MM/YYYY`` formats if the given ``dayfirst`` option could not be respected - now, a warning is raised in the case of delimited date strings (e.g. ``31-12-2012``) (:issue:`12585`) -- +-Bug in :class:'Series' to_numeric as inconsistent behaviour for datatime object (:issue:'43280') Timedelta ^^^^^^^^^ diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index cf8f4fee62a07..61646bf95d4dd 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -130,19 +130,6 @@ def to_numeric(arg, errors="raise", downcast=None): 1 2.1 2 3.0 dtype: Float32 - - Datetime dTypes is supported - - >>> s = pd.to_numeric(datetime(2021, 8, 22), errors="coerce") - 0 20210822 - dtype: Int64 - >>> s = pd.to_numeric(pd.NaT, errors="coerce") - nan - >>> s = pd.to_numeric(pd.Series(datetime(2021, 8, 22)), errors="coerce") - 0 20210822 - dtype: Int64 - >>> s = pd.to_numeric(pd.Series(pd.NaT), errors="coerce") - NaN """ if downcast not in (None, "integer", "signed", "unsigned", "float"): raise ValueError("invalid downcasting method provided") diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index 643a5617abbeb..ff0e446f697de 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -789,3 +789,29 @@ def test_to_numeric_scientific_notation(): result = to_numeric("1.7e+308") expected = np.float64(1.7e308) assert result == expected + + +def test_to_numeric_series_date(): + #GH 43280 + result = pd.to_numeric(pd.Series(datetime(2021, 8, 22)), errors="coerce") + expected = np.Int64(20210822) + assert result == expected + +def test_to_numeric_series_nat(): + #GH 43280 + result = pd.to_numeric(pd.Series(pd.NaT), errors="coerce") + expected = np.float64(NaN) + assert result == expected + +def test_to_numeric_scalar_date(): + #GH 43280 + result = pd.to_numeric(datetime(2021, 8, 22), errors="coerce") + expected = np.Int64(20210822) + assert result == expected + +def test_to_numeric_scalar_nat(): + #GH 43280 + result = pd.to_numeric(pd.NaT, errors="coerce") + expected = np.float64(NaN) + assert result == expected + From a4ae1cc1d643d2cf2e82471c542a69244310b408 Mon Sep 17 00:00:00 2001 From: navaneethan2503 Date: Tue, 31 Aug 2021 19:58:25 +0530 Subject: [PATCH 4/4] changed indentation error and tests --- doc/source/whatsnew/v1.4.0.rst | 2 +- pandas/core/tools/numeric.py | 5 ++++- pandas/tests/tools/test_to_numeric.py | 13 ++++++------- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/doc/source/whatsnew/v1.4.0.rst b/doc/source/whatsnew/v1.4.0.rst index 9224dd41d5e9c..2249c03d52d50 100644 --- a/doc/source/whatsnew/v1.4.0.rst +++ b/doc/source/whatsnew/v1.4.0.rst @@ -267,7 +267,7 @@ Datetimelike ^^^^^^^^^^^^ - Bug in :class:`DataFrame` constructor unnecessarily copying non-datetimelike 2D object arrays (:issue:`39272`) - :func:`to_datetime` would silently swap ``MM/DD/YYYY`` and ``DD/MM/YYYY`` formats if the given ``dayfirst`` option could not be respected - now, a warning is raised in the case of delimited date strings (e.g. ``31-12-2012``) (:issue:`12585`) --Bug in :class:'Series' to_numeric as inconsistent behaviour for datatime object (:issue:'43280') +-Bug in :class:'Series and scalar' to_numeric as inconsistent behaviour for datatime object (:issue:'43280') Timedelta ^^^^^^^^^ diff --git a/pandas/core/tools/numeric.py b/pandas/core/tools/numeric.py index 61646bf95d4dd..d42bcc43f3bc9 100644 --- a/pandas/core/tools/numeric.py +++ b/pandas/core/tools/numeric.py @@ -180,7 +180,10 @@ def to_numeric(arg, errors="raise", downcast=None): if is_numeric_dtype(values_dtype): pass elif is_datetime_or_timedelta_dtype(values_dtype): - + if pd.isnull(arg.values): + values = np.nan + else: + values = pd.to_datetime(values).strftime("%Y%m%d").astype(np.int64) else: values = ensure_object(values) coerce_numeric = errors not in ("ignore", "raise") diff --git a/pandas/tests/tools/test_to_numeric.py b/pandas/tests/tools/test_to_numeric.py index ff0e446f697de..8c1b1df053acd 100644 --- a/pandas/tests/tools/test_to_numeric.py +++ b/pandas/tests/tools/test_to_numeric.py @@ -794,24 +794,23 @@ def test_to_numeric_scientific_notation(): def test_to_numeric_series_date(): #GH 43280 result = pd.to_numeric(pd.Series(datetime(2021, 8, 22)), errors="coerce") - expected = np.Int64(20210822) - assert result == expected + expected = pd.Series([20210822]) + tm.assert_series_equal(result, expected) def test_to_numeric_series_nat(): #GH 43280 result = pd.to_numeric(pd.Series(pd.NaT), errors="coerce") - expected = np.float64(NaN) - assert result == expected + expected = pd.Series([np.nan]) + tm.assert_series_equal(result, expected) def test_to_numeric_scalar_date(): #GH 43280 result = pd.to_numeric(datetime(2021, 8, 22), errors="coerce") - expected = np.Int64(20210822) + expected = np.int64(20210822) assert result == expected def test_to_numeric_scalar_nat(): #GH 43280 result = pd.to_numeric(pd.NaT, errors="coerce") - expected = np.float64(NaN) - assert result == expected + assert pd.isnull(result)