Skip to content

Commit ebd9ebd

Browse files
authored
BUG: DataFrame.std(skipna=False) with td64 dtype (#37392)
1 parent 85621a4 commit ebd9ebd

File tree

4 files changed

+28
-3
lines changed

4 files changed

+28
-3
lines changed

doc/source/whatsnew/v1.2.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ Numeric
402402
- Bug in :class:`DataFrame` arithmetic ops incorrectly accepting keyword arguments (:issue:`36843`)
403403
- Bug in :class:`IntervalArray` comparisons with :class:`Series` not returning :class:`Series` (:issue:`36908`)
404404
- Bug in :class:`DataFrame` allowing arithmetic operations with list of array-likes with undefined results. Behavior changed to raising ``ValueError`` (:issue:`36702`)
405+
- Bug in :meth:`DataFrame.std`` with ``timedelta64`` dtype and ``skipna=False`` (:issue:`37392`)
405406

406407
Conversion
407408
^^^^^^^^^^

pandas/core/nanops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ def _maybe_get_mask(
228228
# Boolean data cannot contain nulls, so signal via mask being None
229229
return None
230230

231-
if skipna:
231+
if skipna or needs_i8_conversion(values.dtype):
232232
mask = isna(values)
233233

234234
return mask

pandas/tests/arrays/test_timedeltas.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
import pandas as pd
55
import pandas._testing as tm
6+
from pandas.core import nanops
67
from pandas.core.arrays import TimedeltaArray
78

89

@@ -288,12 +289,19 @@ def test_std(self):
288289
assert isinstance(result, pd.Timedelta)
289290
assert result == expected
290291

292+
result = nanops.nanstd(np.asarray(arr), skipna=True)
293+
assert isinstance(result, pd.Timedelta)
294+
assert result == expected
295+
291296
result = arr.std(skipna=False)
292297
assert result is pd.NaT
293298

294299
result = tdi.std(skipna=False)
295300
assert result is pd.NaT
296301

302+
result = nanops.nanstd(np.asarray(arr), skipna=False)
303+
assert result is pd.NaT
304+
297305
def test_median(self):
298306
tdi = pd.TimedeltaIndex(["0H", "3H", "NaT", "5H06m", "0H", "2H"])
299307
arr = tdi.array
@@ -307,8 +315,8 @@ def test_median(self):
307315
assert isinstance(result, pd.Timedelta)
308316
assert result == expected
309317

310-
result = arr.std(skipna=False)
318+
result = arr.median(skipna=False)
311319
assert result is pd.NaT
312320

313-
result = tdi.std(skipna=False)
321+
result = tdi.median(skipna=False)
314322
assert result is pd.NaT

pandas/tests/frame/test_analytics.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -753,6 +753,22 @@ def test_operators_timedelta64(self):
753753
assert df["off1"].dtype == "timedelta64[ns]"
754754
assert df["off2"].dtype == "timedelta64[ns]"
755755

756+
def test_std_timedelta64_skipna_false(self):
757+
# GH#37392
758+
tdi = pd.timedelta_range("1 Day", periods=10)
759+
df = DataFrame({"A": tdi, "B": tdi})
760+
df.iloc[-2, -1] = pd.NaT
761+
762+
result = df.std(skipna=False)
763+
expected = Series(
764+
[df["A"].std(), pd.NaT], index=["A", "B"], dtype="timedelta64[ns]"
765+
)
766+
tm.assert_series_equal(result, expected)
767+
768+
result = df.std(axis=1, skipna=False)
769+
expected = Series([pd.Timedelta(0)] * 8 + [pd.NaT, pd.Timedelta(0)])
770+
tm.assert_series_equal(result, expected)
771+
756772
def test_sum_corner(self):
757773
empty_frame = DataFrame()
758774

0 commit comments

Comments
 (0)