-
-
Notifications
You must be signed in to change notification settings - Fork 11.3k
BUG: allow MaskedArray min/max with dtype=object #29576
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
base: main
Are you sure you want to change the base?
Changes from all commits
2a97fee
2642203
822ba2d
52d5955
fb1604e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -191,6 +191,39 @@ class MaskError(MAError): | |
default_filler["M8[" + v + "]"] = np.datetime64("NaT", v) | ||
default_filler["m8[" + v + "]"] = np.timedelta64("NaT", v) | ||
|
||
|
||
class _UniversalInfinity: | ||
def __init__(self, neg=False): | ||
self.neg = neg | ||
|
||
def __le__(self, other): | ||
return self.neg | ||
|
||
def __lt__(self, other): | ||
return self.neg and self != other | ||
|
||
def __ge__(self, other): | ||
return not self.neg | ||
|
||
def __gt__(self, other): | ||
return not self.neg and self != other | ||
|
||
def __eq__(self, other): | ||
return isinstance(other, _UniversalInfinity) and self.neg == other.neg | ||
|
||
def __hash__(self): | ||
return hash(self.neg) | ||
|
||
def __neg__(self): | ||
return _UniversalInfinity(not self.neg) | ||
|
||
def __pos__(self): | ||
return self | ||
|
||
def __repr__(self): | ||
return "-uinf" if self.neg else "uinf" | ||
|
||
|
||
float_types_list = [np.half, np.single, np.double, np.longdouble, | ||
np.csingle, np.cdouble, np.clongdouble] | ||
|
||
|
@@ -211,6 +244,8 @@ class MaskError(MAError): | |
min_val, max_val = info.min, info.max | ||
elif scalar_dtype.kind == "b": | ||
min_val, max_val = 0, 1 | ||
elif scalar_dtype.kind == "O": | ||
min_val, max_val = -_UniversalInfinity(), _UniversalInfinity() | ||
else: | ||
min_val, max_val = None, None | ||
|
||
|
@@ -5942,8 +5977,9 @@ def min(self, axis=None, out=None, fill_value=None, keepdims=np._NoValue): | |
# No explicit output | ||
if out is None: | ||
result = self.filled(fill_value).min( | ||
axis=axis, out=out, **kwargs).view(type(self)) | ||
if result.ndim: | ||
axis=axis, out=out, **kwargs) | ||
if isinstance(result, ndarray) and result.ndim: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is an (extreme) edge case I am aware of here that my code fails to address: ideally, I think that x = np.array([1, 2])
assert np.fromiter([x], dtype=object).view(np.ma.MaskedArray).min() is x should pass, but with my change, x will get erroneously converted to a masked array when returned by This is identical to the old behavior, so it's not necessarily a problem, but it is a failure of my assumptions: initially when working on this PR, I thought I only needed to worry about arrays containing 0-D array objects, since arrays of higher dimension are not orderable (and so you'd just get an error when calling I'm not sure if this is actually worth fixing though. Thoughts? |
||
result = result.view(type(self)) | ||
# Set the mask | ||
result.__setmask__(newmask) | ||
# Get rid of Infs | ||
|
@@ -6047,8 +6083,9 @@ def max(self, axis=None, out=None, fill_value=None, keepdims=np._NoValue): | |
# No explicit output | ||
if out is None: | ||
result = self.filled(fill_value).max( | ||
axis=axis, out=out, **kwargs).view(type(self)) | ||
if result.ndim: | ||
axis=axis, out=out, **kwargs) | ||
if isinstance(result, ndarray) and result.ndim: | ||
result = result.view(type(self)) | ||
# Set the mask | ||
result.__setmask__(newmask) | ||
# Get rid of Infs | ||
|
Uh oh!
There was an error while loading. Please reload this page.