Skip to content
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

ExtensionArray.Round method and tests #54582

Open
wants to merge 37 commits into
base: main
Choose a base branch
from

Conversation

andrewgsavage
Copy link

@andrewgsavage andrewgsavage commented Aug 16, 2023

This adds abstract round method in ExtensionOpsMixin to tell EA authors to implement round, and provides a round test.

@mroeschke mroeschke added the ExtensionArray Extending pandas with custom dtypes or arrays. label Aug 25, 2023
@@ -349,6 +349,10 @@ def test_map_raises(self, data, na_action):
with pytest.raises(ValueError, match=msg):
data.map(lambda x: np.nan, na_action=na_action)

@pytest.mark.xfail(reason="SparseArray.round not implemented.")
Copy link
Member

Choose a reason for hiding this comment

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

why doesnt the base class implementation work here?

@andrewgsavage
Copy link
Author

Any pointers on how to get mypy to accept two function signitures for round? Datetimelikes get overridden:

    def round(self, decimals: int = 0, *args, **kwargs) -> Self:

gets overridden by

    def round(
        self,
        freq,
        ambiguous: TimeAmbiguous = "raise",
        nonexistent: TimeNonexistent = "raise",
    ) -> Self:

@mroeschke
Copy link
Member

If the typing overload decorator doesn't work I think in this case it's OK to ignore the mypy failures since it's a known differnece.

https://docs.python.org/3/library/typing.html#overload

@@ -1094,7 +1094,8 @@ def round(self, decimals: int = 0, *args, **kwargs) -> Self:
DataFrame.round : Round values of a DataFrame.
Series.round : Round values of a Series.
"""
return type(self)(pc.round(self._pa_array, ndigits=decimals))
result = pc.round(self._pa_array, ndigits=decimals)
return type(self)(result.cast(self._pa_array.type))
Copy link
Member

Choose a reason for hiding this comment

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

Why is this cast needed?


def test_round(self, data):
if not data.dtype._is_numeric or data.dtype._is_boolean:
pytest.skip("Round is only valid for numeric non-boolean dtypes")
Copy link
Member

Choose a reason for hiding this comment

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

Can you test that would raise a TypeError instead?

f"Cannot round {type(self)} dtype as it is non-numeric or boolean"
)
return self._from_sequence(
[round(element) if not isna(element) else element for element in self],
Copy link
Member

Choose a reason for hiding this comment

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

self.isna or the self.dtype.na_value should probably be used to check for na instead of isna

@andrewgsavage
Copy link
Author

this is ready for review again

@kernstock
Copy link

Let's do this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ExtensionArray Extending pandas with custom dtypes or arrays.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG: Series.round() expects ExtensionArray.round() to be implemented
4 participants