Skip to content

Commit f08a1e6

Browse files
jbrockmendelWillAyd
authored andcommitted
BUG: timedelta64(NaT) incorrectly treated as datetime in some dataframe ops (#28049)
1 parent 3bd222d commit f08a1e6

File tree

3 files changed

+25
-3
lines changed

3 files changed

+25
-3
lines changed

doc/source/whatsnew/v1.0.0.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,8 @@ Datetimelike
180180
- Addition and subtraction of integer or integer-dtype arrays with :class:`Timestamp` will now raise ``NullFrequencyError`` instead of ``ValueError`` (:issue:`28268`)
181181
- Bug in :class:`Series` and :class:`DataFrame` with integer dtype failing to raise ``TypeError`` when adding or subtracting a ``np.datetime64`` object (:issue:`28080`)
182182
- Bug in :class:`Week` with ``weekday`` incorrectly raising ``AttributeError`` instead of ``TypeError`` when adding or subtracting an invalid type (:issue:`28530`)
183-
183+
- Bug in :class:`DataFrame` arithmetic operations when operating with a :class:`Series` with dtype `'timedelta64[ns]'` (:issue:`28049`)
184+
-
184185

185186
Timedelta
186187
^^^^^^^^^

pandas/core/ops/__init__.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -498,8 +498,19 @@ def column_op(a, b):
498498
# in which case we specifically want to operate row-by-row
499499
assert right.index.equals(left.columns)
500500

501-
def column_op(a, b):
502-
return {i: func(a.iloc[:, i], b.iloc[i]) for i in range(len(a.columns))}
501+
if right.dtype == "timedelta64[ns]":
502+
# ensure we treat NaT values as the correct dtype
503+
# Note: we do not do this unconditionally as it may be lossy or
504+
# expensive for EA dtypes.
505+
right = np.asarray(right)
506+
507+
def column_op(a, b):
508+
return {i: func(a.iloc[:, i], b[i]) for i in range(len(a.columns))}
509+
510+
else:
511+
512+
def column_op(a, b):
513+
return {i: func(a.iloc[:, i], b.iloc[i]) for i in range(len(a.columns))}
503514

504515
elif isinstance(right, ABCSeries):
505516
assert right.index.equals(left.index) # Handle other cases later

pandas/tests/frame/test_arithmetic.py

+10
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,16 @@ def test_arith_flex_zero_len_raises(self):
457457

458458

459459
class TestFrameArithmetic:
460+
def test_td64_op_nat_casting(self):
461+
# Make sure we don't accidentally treat timedelta64(NaT) as datetime64
462+
# when calling dispatch_to_series in DataFrame arithmetic
463+
ser = pd.Series(["NaT", "NaT"], dtype="timedelta64[ns]")
464+
df = pd.DataFrame([[1, 2], [3, 4]])
465+
466+
result = df * ser
467+
expected = pd.DataFrame({0: ser, 1: ser})
468+
tm.assert_frame_equal(result, expected)
469+
460470
def test_df_add_2d_array_rowlike_broadcasts(self):
461471
# GH#23000
462472
arr = np.arange(6).reshape(3, 2)

0 commit comments

Comments
 (0)