Skip to content

Unable to test equality of structured dtypes with no fields #13438

Closed

Description

@mcara

If a structure type has no fields, equality throws

>>> a = np.zeros(10, dtype=[])
>>> a == a
ValueError: No fields found.

Original report:

Test for equality of empty masked arrays raises an exception.

Reproducing code example:

In [1]: import sys, numpy; print(numpy.__version__, sys.version)
1.16.3 3.6.1 (default, May 18 2017, 16:32:13) 
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)]

In [2]: a = numpy.ma.masked_array([], dtype=[], masked=False)  # or masked=True

In [3]: a == None

Error message:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-3-991e7ea0a64c> in <module>
----> 1 a == None

~/.../lib/python3.6/site-packages/numpy/ma/core.py in __eq__(self, other)
   4043         and other considered equal only if both were fully masked.
   4044         """
-> 4045         return self._comparison(other, operator.eq)
   4046 
   4047     def __ne__(self, other):

~/.../lib/python3.6/site-packages/numpy/ma/core.py in _comparison(self, other, compare)
   3996             # Now take care of the mask; the merged mask should have an item
   3997             # masked if all fields were masked (in one and/or other).
-> 3998             mask = (mask == np.ones((), mask.dtype))
   3999 
   4000         else:

ValueError: No fields found.

Numpy/Python version information:

1.16.3 3.6.1 (default, May 18 2017, 16:32:13)
[GCC 4.2.1 Compatible Apple LLVM 8.1.0 (clang-802.0.42)]

Activity

  1. seberg commented on May 1, 2019

    @seberg
    Member

    Uggh, should structured data types with no fields even be allowed?

    In any case, the error is somewhat correct, at least not specific to masked arrays. While it does not happen for arrays, that is only because we replace the error with False currently (and we may at some point change that, its been long deprecated, but I think there have been opinions against actually going through with it).

    Frankly, I am not sure we should take action here. Out of curiosity do you actually have a use case for this dtype?

  2. changed the title [-]Unable to test equality of empty masked arrays[/-] [+]Unable to test equality of structured dtypes with no fields[/+] on May 1, 2019
  3. eric-wieser commented on May 1, 2019

    @eric-wieser
    Member

    Updated the top-post and title to reflect that masked arrays are irrelevant here.

    I'd argue this should just return True, in the same way that () == () is True.

  4. seberg commented on May 1, 2019

    @seberg
    Member

    @eric-wieser yes, sure (or an array of True). What I am not sure about is, what the point of a no field structured type is. On the other hand, I guess there is also no real reason against just allowing it.

  5. mcara commented on May 1, 2019

    @mcara
    Author

    should structured data types with no fields even be allowed?

    I honestly do not know, but currently you do and they crash, occasionally. This issue arose from astropy/astropy#8647 where I am trying to make Table.as_array() to return an empty array when a table is empty - for consistency purpose. When the table is masked (btw, sorry for carrying over masking from tables to the title of this issue), it creates an empty structured array. For this type of array testing for equality to something crashes.

    I do not disagree with you that this is a rare situation but I think we should try to be consistent in how we handle edge cases. There are a couple of places in astropy or affiliated packages when a function may return an empty table (based on my memory - I may be wrong). Maybe we can do things differently if this is not a supported usage of arrays. But my first impression was that if an empty array is allowed to be created then why couldn't I use it for comparison.

  6. seberg commented on May 1, 2019

    @seberg
    Member

    Yeah, I was a bit misguided, there is definitely no point in not allowing this (especially going backward!), so the void comparison code really should just be capable of handling this.

  7. eric-wieser commented on Jun 8, 2019

    @eric-wieser
    Member

    or an array of True

    This unfortunately is difficult to do correctly - not only does the shape of this array have to be correct, but it should probably inherit the right type through the array_ufunc mechanism.

    I think this issue might be unfixable until void comparison is done via a ufunc.

  8. seberg commented on Jun 9, 2019

    @seberg
    Member

    Well, doing void comparison via a ufunc is very much doable though. And . while string ufuncs would be a bit annoying, a string comparison ufunc should be very much doable. Right now I would prefer not to put it on the agenda though probably. 1.17 is almost there, and I have some hope that we have some changes until 1.18... OTOH, the loops itself would still all work fine I suppose.

  9. added a commit that references this issue on Sep 5, 2019
    d6f7524
  10. mattip commented on Sep 8, 2019

    @mattip
    Member

    Confirm that #14393 closed this:

    >>> a = np.zeros(10, dtype=[])
    >>> a == a
    array([ True,  True,  True,  True,  True,  True,  True,  True,  True,
            True])
    
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions