Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 19 additions & 4 deletions xarray/core/variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,9 @@ def _maybe_wrap_data(data):

def _possibly_convert_objects(values):
"""Convert object arrays into datetime64 and timedelta64 according
to the pandas convention. For backwards compat, as of 3.0.0 pandas,
object dtype inputs are cast to strings by `pandas.Series`
to the pandas convention. Object dtype inputs that are inferred to be
strings are returned unchanged. For backwards compat, as of 3.0.0 pandas,
the remaining object dtype inputs are cast to strings by `pandas.Series`
but we output them as object dtype with the input metadata preserved as well.


Expand All @@ -220,8 +221,22 @@ def _possibly_convert_objects(values):
* pd.Timestamp
* pd.Timedelta
"""
as_series = pd.Series(values.ravel(), copy=False)
result = np.asarray(as_series).reshape(values.shape)
inferred = pd.api.types.infer_dtype(values.ravel(), skipna=True)

if inferred == "string":
return values
elif inferred == "datetime":
result = pd.to_datetime(values.ravel()).to_numpy().reshape(values.shape)
elif inferred == "timedelta":
result = pd.to_timedelta(values.ravel()).to_numpy().reshape(values.shape)
elif inferred in ["datetime64", "timedelta64"]:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's add a comment about infer_dtype dropping units

@JJFlorian JJFlorian Jul 30, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, I would say the cast drops them

# Casting drops unit info for these cases;
# fall back to pd.Series roundtrip, which preserves them.
as_series = pd.Series(values.ravel(), copy=False)
result = np.asarray(as_series).reshape(values.shape)
else:
return values

if not result.flags.writeable:
# GH8843, pandas copy-on-write mode creates read-only arrays by default
try:
Expand Down
3 changes: 3 additions & 0 deletions xarray/tests/test_variable.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ def var():
[
np.array(["a", "bc", "def"], dtype=object),
np.array(["2019-01-01", "2019-01-02", "2019-01-03"], dtype="datetime64[ns]"),
np.array([datetime(2000, 1, 1), datetime(2000, 1, 2)], dtype=object),
np.array([timedelta(seconds=1), timedelta(seconds=2)], dtype=object),
np.array([1, "a"], dtype=object),
],
)
def test_as_compatible_data_writeable(data):
Expand Down
Loading