Skip to content

Fix object array infer string perf 11470 - #11484

Open
JJFlorian wants to merge 6 commits into
pydata:mainfrom
JJFlorian:fix-object-array-infer-string-perf-11470
Open

Fix object array infer string perf 11470#11484
JJFlorian wants to merge 6 commits into
pydata:mainfrom
JJFlorian:fix-object-array-infer-string-perf-11470

Conversation

@JJFlorian

Copy link
Copy Markdown
Contributor

Description

As discussed in #11470, this PR optimizes the _possibly_convert_objects function. It uses pd.api.types.infer_dtype to classify the values, then converts using a targeted pd.to_datetime/pd.to_timedelta call instead of the generic pd.Series roundtrip where safe to do so. This is only the case for string, datetime, and timedelta.

datetime64 and timedelta64 get tricky because pd.to_datetime/pd.to_timedelta re-infer units rather than preserving the input's existing unit. So for these 2 cases, and all other return types of the infer_dtype, I still use the pd.Series roundtrip for now.

Is there a way to cast these 2 datatypes while preserving their units?

I added 3 new cases to test_as_compatible_data_writeable covering the datetime and timedelta fast paths. Without them, an implementation that returns the pd.to_datetime/pd.to_timedelta result directly (bypassing the existing writeable fix) would still pass the full test suite, but would silently return read only arrays instead of the writeable arrays xarray currently guarantees.

Results

With the example from the issue, we now get:

infer_string=False: 55.3ms # was 0.1ms
infer_string=True: 56.0ms # was 606.3ms

Checklist

AI Disclosure

  • This PR contains AI-generated content.
    • I have tested any AI-generated content in my PR.
    • I take responsibility for any AI-generated content in my PR. Tools: {e.g., Claude, Codex, GitHub Copilot, ChatGPT, etc.}

Comment thread xarray/core/variable.py
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

@JJFlorian
JJFlorian marked this pull request as ready for review July 31, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Construction of arrays with object dtype very slow when Pandas future.infer_string is enabled

2 participants