-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
API: how to check for "logical" equality of dtypes? #60305
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
Comments
And maybe an additional question is how to propagate that notion of "exact equality" vs "logical equality" into methods like |
One idea is to make IMHO, let |
Something like |
I think these should compare as equal if they are logically equivalent; otherwise we are back to the issue of exposing the implementation detail to end users. So I think the reverse of being proposed is what we should have. By default, equality comparisons use the logical semantics, and if you wanted a more granular physical comparison you should use a dedicated function. I think we have a prior art for that already when considering |
@WillAyd that would create a change of behavior. See this example: >>> s = pd.Series([1,2,3], dtype="Int64")
>>> s2 = pd.Series([1,2,3])
>>> s
0 1
1 2
2 3
dtype: Int64
>>> s2
0 1
1 2
2 3
dtype: int64
>>> s.dtype == s2.dtype
False So you're proposing that |
In the long run yes...although we definitely need to be careful about the steps that we take to get there. I'm also coming from the perspective that we've discussed in PDEP-13, where |
There seems to be a concern about changing the behavior of equality checks, as it could affect users who rely on the current exact equality checks.
as @WillAyd mentions this is exposing the implementation detail to end users. So could it be considered reasonable to argue that this is a bug and a change would be a bugfix not a change in behavior for just this dtype in isolation which is still currently considered experimental? |
Yea that's an interesting point that @simonjayhawkins brings up. Do we think there's a huge risk to changing that behavior for strings today? |
I am very confused by your discussion around logical equality of dtypes, considering that you never defined what logical means. Do you consider We can even consider "string[python]"=="string[pyarrow]" one is replacing in-place, not the other one. This is indeed an implementation detail that I would not qualify as a detail is you work with large datastructures. Personally, I would expect to see Using |
@arnaudlegout thanks for the feedback.
There is a larger (although incomplete) discussion of this in #58455 that is good for context
Nope :-) These types have different front-end requirements for the user, i.e. they store different widths. In the integral space, we have three different implementations of a 64 bit integer. The default implementation uses NumPy storage, the second iteration we did uses pandas custom code on top of NumPy storage, and the third int64 implementation uses PyArrow. The logical type system would consider all of those equal. That is still a ways off though and needs further discussion in that PDEP. The only real logical implementation we've tried today is our string data type that is getting implemented in 3.0
Neither of these is fixed size, they just use a different null sentinel (str uses np.nan, string uses pd.NA)
While there are theoretically some differences to how assignment can work with either of these storage types, we don't make any guarantees about that through our API. inplace modification is something we have been moving away from for quite some time; in 3.0 copy-on-write becomes the default behavior for all types. That speaks to the general issue though in that by exposing type implementation details, we are allowing users to make assumptions about how we manage types that we ourselves do not actually adhere to. We are not developing |
== should remain strict on the dtype object. It is often used for eg “can I do a binary operation between these two without a cast” (eg get_indexer). maybe dtype.logical_dtype attribute which can use ==? |
Assume you have a series, which has a certain dtype. In the case that this dtype is an instance of potentially multiple variants of a logical dtype (for example, string backed by python or backed by pyarrow), how do you check for the "logical" equality of such dtypes?
For checking the logical equality for one series, you have the option to compare it with the generic string alias (which will return True for any variant of it) or checking the dtype with
isinstance
or someis_..._dtype
(although we have deprecated some of those). Using string dtype as the example:When you want to check if two serieses have the same dtype, the
==
will check for exact equality (in the string dtype example, the below can evaluate to False even if both are a StringDtype, but have a different storage):But so how to check this logical equality for two dtypes? In the example, how to know that both dtypes are representing the same logical dtype (i.e. both a StringDtype instance), without necessarily wanting to check the exact type (i.e. the user doesn't necessarily know it are string dtypes, just want to check if they are logically the same)
Do we want some other API here that is a bit more user friendly? (just brainstorming, something like
dtype1.is_same_type(dtype2)
, or a function, ..)This is important in the discussion around logical dtypes (#58455), but so it is already an issue for the new string dtype as well in pandas 3.0
cc @WillAyd @Dr-Irv @jbrockmendel (tagging some people that were most active in the logical dtypes discussion)
The text was updated successfully, but these errors were encountered: