Skip to content

Commit ddbeca6

Browse files
authored
API: make min/max on empty datetime df consistent with datetime serie… (#33911)
1 parent cb7b294 commit ddbeca6

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

doc/source/whatsnew/v1.1.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -563,6 +563,7 @@ Datetimelike
563563
- Bug in :meth:`DatetimeIndex.intersection` losing ``freq`` and timezone in some cases (:issue:`33604`)
564564
- Bug in :class:`DatetimeIndex` addition and subtraction with some types of :class:`DateOffset` objects incorrectly retaining an invalid ``freq`` attribute (:issue:`33779`)
565565
- Bug in :class:`DatetimeIndex` where setting the ``freq`` attribute on an index could silently change the ``freq`` attribute on another index viewing the same data (:issue:`33552`)
566+
- :meth:`DataFrame.min`/:meth:`DataFrame.max` not returning consistent result with :meth:`Series.min`/:meth:`Series.max` when called on objects initialized with empty :func:`pd.to_datetime`
566567
- Bug in :meth:`DatetimeIndex.intersection` and :meth:`TimedeltaIndex.intersection` with results not having the correct ``name`` attribute (:issue:`33904`)
567568
- Bug in :meth:`DatetimeArray.__setitem__`, :meth:`TimedeltaArray.__setitem__`, :meth:`PeriodArray.__setitem__` incorrectly allowing values with ``int64`` dtype to be silently cast (:issue:`33717`)
568569

pandas/core/nanops.py

+6-2
Original file line numberDiff line numberDiff line change
@@ -384,8 +384,12 @@ def _na_for_min_count(
384384
else:
385385
assert axis is not None # assertion to make mypy happy
386386
result_shape = values.shape[:axis] + values.shape[axis + 1 :]
387-
result = np.empty(result_shape, dtype=values.dtype)
388-
result.fill(fill_value)
387+
# calling np.full with dtype parameter throws an ValueError when called
388+
# with dtype=np.datetime64 and and fill_value=pd.NaT
389+
try:
390+
result = np.full(result_shape, fill_value, dtype=values.dtype)
391+
except ValueError:
392+
result = np.full(result_shape, fill_value)
389393
return result
390394

391395

pandas/tests/frame/test_analytics.py

+27
Original file line numberDiff line numberDiff line change
@@ -1258,3 +1258,30 @@ def test_min_max_dt64_with_NaT(self):
12581258
res = df.max()
12591259
exp = pd.Series([pd.NaT], index=["foo"])
12601260
tm.assert_series_equal(res, exp)
1261+
1262+
def test_min_max_dt64_api_consistency_with_NaT(self):
1263+
# Calling the following sum functions returned an error for dataframes but
1264+
# returned NaT for series. These tests check that the API is consistent in
1265+
# min/max calls on empty Series/DataFrames. See GH:33704 for more
1266+
# information
1267+
df = pd.DataFrame(dict(x=pd.to_datetime([])))
1268+
expected_dt_series = pd.Series(pd.to_datetime([]))
1269+
# check axis 0
1270+
assert (df.min(axis=0).x is pd.NaT) == (expected_dt_series.min() is pd.NaT)
1271+
assert (df.max(axis=0).x is pd.NaT) == (expected_dt_series.max() is pd.NaT)
1272+
1273+
# check axis 1
1274+
tm.assert_series_equal(df.min(axis=1), expected_dt_series)
1275+
tm.assert_series_equal(df.max(axis=1), expected_dt_series)
1276+
1277+
def test_min_max_dt64_api_consistency_empty_df(self):
1278+
# check DataFrame/Series api consistency when calling min/max on an empty
1279+
# DataFrame/Series.
1280+
df = pd.DataFrame(dict(x=[]))
1281+
expected_float_series = pd.Series([], dtype=float)
1282+
# check axis 0
1283+
assert np.isnan(df.min(axis=0).x) == np.isnan(expected_float_series.min())
1284+
assert np.isnan(df.max(axis=0).x) == np.isnan(expected_float_series.max())
1285+
# check axis 1
1286+
tm.assert_series_equal(df.min(axis=1), expected_float_series)
1287+
tm.assert_series_equal(df.min(axis=1), expected_float_series)

0 commit comments

Comments
 (0)