Skip to content

Add native to_pandas byteorder conversion for ArrayWrapper Tables - #11294

Merged
mhvk merged 3 commits into
astropy:masterfrom
dhomeier:pandas-arraywrapper-endianess
Feb 3, 2021
Merged

mhvk merged 3 commits into
astropy:masterfrom
dhomeier:pandas-arraywrapper-endianess

Conversation

@dhomeier

@dhomeier dhomeier commented Feb 2, 2021

Copy link
Copy Markdown
Contributor

Description

Follow-up to #11288

This handles some additional corner cases for MixedArray-like tables, that were exempt from the byteorder/isnative checks since they were first converted to Pandas Series objects.
Now checking and fixing byteorder first before any conversions to Pandas types, added an ArrayWrapper with non-native byteorder to MIXIN_COLS for testing.
Since pickle and init_from_class are not preserving byteorder in this case, their tests in test_info_preserved_pickle_copy_init are intercepted accordingly.

@dhomeier

dhomeier commented Feb 2, 2021 •

Copy link
Copy Markdown
Contributor Author

I have made the assert conditional in this way since I am not sure how exactly xfail or skip operate in a loop like this – I think pytest.xfail would still perform the assert for all colname, func, attr combinations but ignore all failures in that test call.
Update: found a way to test for the byteorder-independent part of dtype.

In fact one could have let Pandas take care of the entire conversion to native by Series(column, dtype=column.dtype.name) and the like, with the sole exception of the ArrayWrapper types, which it does not understand (me neither 😉)!

@mhvk mhvk left a comment

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.

I like this very much, smaller, simpler code that leaves more stuff to pandas; great!

Only a total nitpick about one test.

Also a quick question for @taldcroft: is byteorder meant to be preserved in pickling? (if so, likely a separate issue, but good to look at it now). I can understand table initialization since by default it makes a copy (which would change the byteorder to native), but pickle is less obvious.

Comment thread astropy/table/tests/test_mixin.py Outdated
m2 = func(m)
for attr in attrs:
assert getattr(m2.info, attr) == getattr(m.info, attr)
if (attr != 'dtype' or getattr(m.info.dtype, 'isnative', True) or

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.

Total nitpick: could you make this 3 lines like

if (attr != 'dtype'
        or getattr(m.info.dtype, 'isnative', True)
        or func in (copy.copy, copy.deepcopy)):

We've moved to having operators at the start of a line (and this would seem clearer).

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.

Thanks, I'd been scratching my head a bit around where we want to put the operators now (and the original version had a lot of and nots...), but could not quickly spot an example...

@taldcroft taldcroft left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks @dhomeier this looks good to me with a 2nd nitpick (in the category of "don't fix code unless it is broken"). 😄

Comment thread astropy/table/table.py Outdated
# Convert int64 to Int64, uint32 to UInt32, etc for nullable types
pd_dtype = pd_dtype.replace('i', 'I').replace('u', 'U')
out[name] = Series(column, dtype=pd_dtype)
pd_dtype = pd_dtype.capitalize().replace('i', 'I')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Another nitpick. I like the original version of this line as being more consistent, as in capitalize any i or u in pd_dtype using replace. If there is nothing logically wrong with the original then please revert.

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.

Sure; I just wanted to use capitalize as a neater method, but then realised that would not be enough to deal with the uints.

@taldcroft

Copy link
Copy Markdown
Member

@mhvk - about pickling and byte order, I haven't thought about this before. Generally speaking I don't think of pickle as a serialization method that is rigorous like that, so I wouldn't expect byte order to be preserved. It is worth nothing that numpy arrays seem to convert from non-native to native byte order when pickled, so that's what I'd expect for astropy Table columns.

@mhvk

mhvk commented Feb 3, 2021

Copy link
Copy Markdown
Contributor

OK on letting pickling be consistent with numpy!

@mhvk mhvk left a comment

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.

Great, thanks!

@mhvk

mhvk commented Feb 3, 2021

Copy link
Copy Markdown
Contributor

Failures unrelated, so merging...

@astrofrog

Copy link
Copy Markdown
Member

@dhomeier - how critical is this to backport to v4.0.x? There are a few non-trivial conflicts due to this PR building on some of the things in #9541 which are not included in v4.0.x.

@dhomeier

Copy link
Copy Markdown
Contributor Author

@astrofrog will 4.0.x support use_nullable_int at all then? Or are there other pd_dtype cases that are broken?
Otherwise I think it's fine to raise an exception instead (re. warning to update to 4.2+) if people enabled use_nullable_int on non-native integer dtypes.

eteq pushed a commit that referenced this pull request Mar 25, 2021
Add native to_pandas byteorder conversion for ArrayWrapper Tables
@eteq eteq modified the milestones: v4.0.5, v4.0.6 Mar 26, 2021
@eteq

eteq commented Mar 26, 2021 •

Copy link
Copy Markdown
Member

Since it's now the only thing holding up 4.0.5 I'm going to make a command decision to say we're going to push this to 4.0.6 - it will be in 4.2.1, though (since it backports cleanly there)(, which will make the changelog a bit confusing. I'll just put it in 4.2.1 for now in the 4.2.x branch.

@dhomeier

dhomeier commented Mar 26, 2021 •

Copy link
Copy Markdown
Contributor Author

@eteq unless the use_nullable_int is going to be backported into LTS at some later time, I think we do not need any of the unsupported *IntNN dtypes and can just leave that block of code out. But since everything has been reordered quite a bit, it's probably best to give that another review for 4.0.6.

@astrofrog

Copy link
Copy Markdown
Member

@dhomeier - I'm going to re-milestone this to v4.0.7 as I can't figure out how to backport this correctly and have the tests still pass. Could you try and open a PR to the v4.0.x branch to manually fix this in that branch?

@astrofrog astrofrog modified the milestones: v4.0.6, v4.0.7 Aug 17, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants