Skip to content

Commit ef5b24d

Browse files
committed
Building a function to handle na date columns
1 parent 0691c5c commit ef5b24d

File tree

2 files changed

+89
-0
lines changed

2 files changed

+89
-0
lines changed

pandas/core/frame.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,8 @@
205205
)
206206
import pandas.plotting
207207

208+
from pandas.core.tools.datetimes import to_datetime
209+
208210
if TYPE_CHECKING:
209211
import datetime
210212

@@ -11632,6 +11634,27 @@ def all(
1163211634
result = result.__finalize__(self, method="all")
1163311635
return result
1163411636

11637+
def convert_date_na_columns(self):
11638+
"""
11639+
Convert all columns containing only dates and nulls in a DataFrame to datetime objects.
11640+
"""
11641+
for col in self.columns:
11642+
if self.is_date_or_null_column(self[col]):
11643+
try:
11644+
self[col] = to_datetime(self[col])
11645+
except (ValueError, TypeError):
11646+
continue
11647+
else:
11648+
continue
11649+
11650+
def is_date_or_null_column(self, column: Series) -> bool:
11651+
"""Check if a pandas Series contains only datetime.date objects or nulls."""
11652+
for value in column:
11653+
from datetime import date
11654+
if not (isna(value) or isinstance(value, date)):
11655+
return False
11656+
return True
11657+
1163511658
@doc(make_doc("min", ndim=2))
1163611659
def min(
1163711660
self,
@@ -11640,6 +11663,7 @@ def min(
1164011663
numeric_only: bool = False,
1164111664
**kwargs,
1164211665
):
11666+
self.convert_date_na_columns()
1164311667
result = super().min(axis, skipna, numeric_only, **kwargs)
1164411668
if isinstance(result, Series):
1164511669
result = result.__finalize__(self, method="min")
@@ -11653,6 +11677,7 @@ def max(
1165311677
numeric_only: bool = False,
1165411678
**kwargs,
1165511679
):
11680+
self.convert_date_na_columns()
1165611681
result = super().max(axis, skipna, numeric_only, **kwargs)
1165711682
if isinstance(result, Series):
1165811683
result = result.__finalize__(self, method="max")
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import pytest
2+
import pandas as pd
3+
import numpy as np
4+
import datetime
5+
6+
7+
def test_min_with_mixed_nan_and_dates():
8+
"""Test min() with mix of NaN and datetime.date objects"""
9+
data = {
10+
"dates": [
11+
np.nan,
12+
np.nan,
13+
datetime.date(2025, 1, 3),
14+
datetime.date(2025, 1, 4),
15+
],
16+
}
17+
df = pd.DataFrame(data)
18+
result = df.min()
19+
expected = pd.Series({"dates": datetime.date(2025, 1, 3)}, dtype="datetime64[ns]")
20+
pd.testing.assert_series_equal(result, expected)
21+
22+
23+
def test_min_with_all_nan():
24+
"""Test min() with all NaN values (should return NaN)"""
25+
data = {
26+
"dates": [
27+
np.nan,
28+
np.nan,
29+
np.nan,
30+
],
31+
}
32+
df = pd.DataFrame(data)
33+
result = df.min()
34+
expected = pd.Series({"dates": np.nan}, dtype="datetime64[ns]")
35+
pd.testing.assert_series_equal(result, expected)
36+
37+
38+
def test_min_with_only_dates():
39+
"""Test min() with only datetime.date objects (no NaN)"""
40+
data = {
41+
"dates": [
42+
datetime.date(2025, 1, 3),
43+
datetime.date(2025, 1, 4),
44+
datetime.date(2025, 1, 1),
45+
],
46+
}
47+
df = pd.DataFrame(data)
48+
result = df.min()
49+
expected = pd.Series({"dates": datetime.date(2025, 1, 1)}, dtype="datetime64[ns]")
50+
pd.testing.assert_series_equal(result, expected)
51+
52+
53+
def test_min_with_mixed_types_error():
54+
"""Test min() with incompatible types (should raise TypeError)"""
55+
data = {
56+
"mixed": [
57+
np.nan,
58+
"string",
59+
datetime.date(2025, 1, 3),
60+
],
61+
}
62+
df = pd.DataFrame(data)
63+
with pytest.raises(TypeError):
64+
df.max()

0 commit comments

Comments
 (0)