From 9dc3d34a87cde5272d8bcc2e21843061f8f20245 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 31 Jan 2020 19:57:31 -0800 Subject: [PATCH 1/2] BUG: Series multiplication with timedelta scalar numexpr path --- doc/source/whatsnew/v1.0.1.rst | 1 + pandas/core/ops/array_ops.py | 5 +++-- pandas/tests/arithmetic/test_numeric.py | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.0.1.rst b/doc/source/whatsnew/v1.0.1.rst index ff8433c7cafd9..fd09f5dc13557 100644 --- a/doc/source/whatsnew/v1.0.1.rst +++ b/doc/source/whatsnew/v1.0.1.rst @@ -44,6 +44,7 @@ Timezones Numeric ^^^^^^^ - Bug in dtypes being lost in ``DataFrame.__invert__`` (``~`` operator) with mixed dtypes (:issue:`31183`) +- Bug in :class:`Series` multiplication when multiplying a numeric :class:`Series` with >10000 elements with a timedelta-like scalar (:issue:`31467`) - Conversion diff --git a/pandas/core/ops/array_ops.py b/pandas/core/ops/array_ops.py index c393b8028113b..3302ed9c219e6 100644 --- a/pandas/core/ops/array_ops.py +++ b/pandas/core/ops/array_ops.py @@ -8,7 +8,7 @@ import numpy as np -from pandas._libs import Timestamp, lib, ops as libops +from pandas._libs import Timedelta, Timestamp, lib, ops as libops from pandas.core.dtypes.cast import ( construct_1d_object_array_from_listlike, @@ -186,11 +186,12 @@ def arithmetic_op( rvalues = maybe_upcast_for_op(rvalues, lvalues.shape) if should_extension_dispatch(left, rvalues) or isinstance( - rvalues, (ABCTimedeltaArray, ABCDatetimeArray, Timestamp) + rvalues, (ABCTimedeltaArray, ABCDatetimeArray, Timestamp, Timedelta) ): # TimedeltaArray, DatetimeArray, and Timestamp are included here # because they have `freq` attribute which is handled correctly # by dispatch_to_extension_op. + # Timedelta is included because numexpr will fail on it, see GH#31457 res_values = dispatch_to_extension_op(op, lvalues, rvalues) else: diff --git a/pandas/tests/arithmetic/test_numeric.py b/pandas/tests/arithmetic/test_numeric.py index 7c0f94001d306..b807391b80e29 100644 --- a/pandas/tests/arithmetic/test_numeric.py +++ b/pandas/tests/arithmetic/test_numeric.py @@ -177,6 +177,28 @@ def test_numeric_arr_mul_tdscalar(self, scalar_td, numeric_idx, box): commute = scalar_td * index tm.assert_equal(commute, expected) + @pytest.mark.parametrize( + "scalar_td", + [ + Timedelta(days=1), + Timedelta(days=1).to_timedelta64(), + Timedelta(days=1).to_pytimedelta(), + ], + ids=lambda x: type(x).__name__, + ) + def test_numeric_arr_mul_tdscalar_numexpr_path(self, scalar_td, box): + arr = np.arange(2 * 10 ** 4) + obj = tm.box_expected(arr, box, transpose=False) + + expected = arr.view("timedelta64[D]").astype("timedelta64[ns]") + expected = tm.box_expected(expected, box, transpose=False) + + result = obj * scalar_td + tm.assert_equal(result, expected) + + result = scalar_td * obj + tm.assert_equal(result, expected) + def test_numeric_arr_rdiv_tdscalar(self, three_days, numeric_idx, box): index = numeric_idx[1:3] From 117af8a3a38a81db6e2a96cd778968fafba5ea1c Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Fri, 31 Jan 2020 20:40:28 -0800 Subject: [PATCH 2/2] 32bit compat --- pandas/tests/arithmetic/test_numeric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/arithmetic/test_numeric.py b/pandas/tests/arithmetic/test_numeric.py index b807391b80e29..51d09a92773b1 100644 --- a/pandas/tests/arithmetic/test_numeric.py +++ b/pandas/tests/arithmetic/test_numeric.py @@ -187,7 +187,7 @@ def test_numeric_arr_mul_tdscalar(self, scalar_td, numeric_idx, box): ids=lambda x: type(x).__name__, ) def test_numeric_arr_mul_tdscalar_numexpr_path(self, scalar_td, box): - arr = np.arange(2 * 10 ** 4) + arr = np.arange(2 * 10 ** 4).astype(np.int64) obj = tm.box_expected(arr, box, transpose=False) expected = arr.view("timedelta64[D]").astype("timedelta64[ns]")