-
-
Notifications
You must be signed in to change notification settings - Fork 18.9k
PARTIAL FIX: Improve leading zeros preservation with dtype=str for dict-based dtypes #62242
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Looks like AI
I did use AI to help draft this. I tried setting up a pandas development environment (both via pip and the Docker image) to create a reproducible test case, but running pytest from the CLI kept failing with a message about pandas._libs.
There seems to be a significant issue with the pyarrow implementation. Specifically, pyarrow does not enforce dtypes during load - it applies them afterward. As a result, integer-to-string conversions lose leading zeros. I wanted to at least contribute a working test that highlights this problem.
@jbrockmendel test is passing now. I have it marked as xfail
for pyarrow only, but you can clearly see the issue. Once the issue is remedied we can remove the try/except block.
We discourage AI-generated PRs since they take more time and effort to review than they do to write. I'll take a look since you took the time to get the CI passing, but in the future please avoid it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
take a look at how we handle xfails elsewhere. we check and add the marker before the meat of the test
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jbrockmendel I considered that option, but it doesn't seem appropriate for this case. The tests only fail for the pyarrow engine, and only because there is an underlying flaw in the pyarrow read logic. Is there another preferred way to handle this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this doesn't merit its own file. try to find plausibly-related tests to put it with
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seemsl ike the tests/io/parser
is the right place, but I don't see any other files there that seem appropriate. could you suggest another place? happy to move it.
big picture adding a test isn't wrong, but not a good use of time. if you'd like to actually fix the issue, i think there are some good comments in the original thread
big picture adding a test isn't wrong, but not a good use of time. if you'd like to actually fix the issue, i think there are some good comments in the original thread
I agree, but the fix doesn't appear to be very straightforward. Happy to work on it if there is some guidance on where to find the relevant pieces. It requires proper mapping of pandas dtypes to pyarrow types, and also handling other logic that pandas supports but pyarrow doesn't (e.g., col index-based dtypes, global dtypes, etc.).
@jbrockmendel I dug into the pandas and PyArrow APIs and landed on a more general fix for the issue. I wasn't sure how to run pytest
locally against the dev branch - my attempts with the Docker container didn't work - so I relied on pandas' test suite.
This patch improves dtype handling during the pyarrow write path by converting supported column-specific dtypes into pyarrow types and passing them via convert_options["column_types"]. However, a few limitations remain:
Known Issues / Remaining Work
- Global dtype support is not implemented
The current logic handles only column-specific dtype dictionaries. Global dtypes (e.g., dtype=str) are ignored, which could lead to inconsistent behavior across engines, especially with things like leading-zero string preservation. Supporting this would require column name/index context, which doesn't seem to be readily available here. I couldn't find a safe and clean way to retrieve it without broader architectural changes.
EDIT: After review, I think this feature would be best handled with a change to the PyArrow API, which we could adapt here quite easily. I've posted that issue here: apache/arrow#47502
-
Unsupported dtypes are silently skipped
If a dtype (e.g., "category") is not mappable to a PyArrow type, we currently drop it from column_types. This fallback behavior avoids breaking the pipeline, but it may lead to silent mismatches when PyArrow falls back to its default inference. We may want to revisit this to either emit warnings or fail explicitly for better visibility. -
Possible redundancy in _finalize_dtype()
Now that dtypes are mapped earlier during the pyarrow conversion, we may no longer need the final call to self._finalize_dtype(). However, it might still be necessary for preserving native pandas types (e.g., CategoricalDtype) in some cases that do not have native pyarrow support.
Uh oh!
There was an error while loading. Please reload this page.
Summary
This PR partially addresses issue #57666 by improving leading zeros preservation when
dtype=str
is used with dictionary-based dtype specifications. While the globaldtype=str
issue with pyarrow engine remains unfixed, this PR resolves the problem for more targeted dtype specifications.Problem
Issue #57666 reports that the pyarrow engine does not preserve leading zeros in numeric-looking strings when
dtype=str
is specified, while other engines correctly preserve them.Solution
dtype={'col': str}
) now properly preserve leading zeros across all enginesdtype=str
still fails with pyarrow engine (marked with xfail for now)What's Fixed vs Still Broken
✅ Now Working:
Next Steps
This PR provides a foundation for the complete fix. The remaining work involves:
dtype
handlingChecklist
doc/source/whatsnew/v3.0.0.rst
Files Changed
pandas/io/parsers/arrow_parser_wrapper.py
- Fix for dict-based dtypespandas/tests/io/parser/test_preserve_leading_zeros.py
- Comprehensive test suiteTest Output
dtype=str
marked as xfail (temporary)