Skip to content

Commit f36494e

Browse files
ilan-golddcherian
authored andcommitted
(fix): don't handle time-dtypes as extension arrays in from_dataframe (#9042)
* (fix): don't handle time-dtypes as extension arrays * (fix): check series type * Add whats-new --------- Co-authored-by: Deepak Cherian <[email protected]> Co-authored-by: Deepak Cherian <[email protected]>
1 parent 409e4f6 commit f36494e

File tree

3 files changed

+28
-1
lines changed

3 files changed

+28
-1
lines changed

doc/whats-new.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ Deprecations
4040

4141
Bug fixes
4242
~~~~~~~~~
43+
- Preserve conversion of timezone-aware pandas Datetime arrays to numpy object arrays
44+
(:issue:`9026`, :pull:`9042`).
45+
By `Ilan Gold <https://github.com/ilan-gold>`_.
4346

4447
- :py:meth:`DataArrayResample.interpolate` and :py:meth:`DatasetResample.interpolate` method now
4548
support aribtrary kwargs such as ``order`` for polynomial interpolation. (:issue:`8762`).

properties/test_pandas_roundtrip.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,16 @@
3030
)
3131

3232

33+
datetime_with_tz_strategy = st.datetimes(timezones=st.timezones())
34+
dataframe_strategy = pdst.data_frames(
35+
[
36+
pdst.column("datetime_col", elements=datetime_with_tz_strategy),
37+
pdst.column("other_col", elements=st.integers()),
38+
],
39+
index=pdst.range_indexes(min_size=1, max_size=10),
40+
)
41+
42+
3343
@st.composite
3444
def datasets_1d_vars(draw) -> xr.Dataset:
3545
"""Generate datasets with only 1D variables
@@ -98,3 +108,15 @@ def test_roundtrip_pandas_dataframe(df) -> None:
98108
roundtripped = arr.to_pandas()
99109
pd.testing.assert_frame_equal(df, roundtripped)
100110
xr.testing.assert_identical(arr, roundtripped.to_xarray())
111+
112+
113+
@given(df=dataframe_strategy)
114+
def test_roundtrip_pandas_dataframe_datetime(df) -> None:
115+
# Need to name the indexes, otherwise Xarray names them 'dim_0', 'dim_1'.
116+
df.index.name = "rows"
117+
df.columns.name = "cols"
118+
dataset = xr.Dataset.from_dataframe(df)
119+
roundtripped = dataset.to_dataframe()
120+
roundtripped.columns.name = "cols" # why?
121+
pd.testing.assert_frame_equal(df, roundtripped)
122+
xr.testing.assert_identical(dataset, roundtripped.to_xarray())

xarray/core/dataset.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7420,7 +7420,9 @@ def from_dataframe(cls, dataframe: pd.DataFrame, sparse: bool = False) -> Self:
74207420
arrays = []
74217421
extension_arrays = []
74227422
for k, v in dataframe.items():
7423-
if not is_extension_array_dtype(v):
7423+
if not is_extension_array_dtype(v) or isinstance(
7424+
v.array, (pd.arrays.DatetimeArray, pd.arrays.TimedeltaArray)
7425+
):
74247426
arrays.append((k, np.asarray(v)))
74257427
else:
74267428
extension_arrays.append((k, v))

0 commit comments

Comments
 (0)