Thanks to visit codestin.com
Credit goes to github.com

Skip to content

API: make all comparisons with NaT false #7001

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

Merged
merged 1 commit into from
Jan 14, 2016
Merged

Conversation

shoyer
Copy link
Member

@shoyer shoyer commented Jan 13, 2016

Now, NaT compares like NaN:

  • NaT != NaT -> True
  • NaT == NaT (and all other comparisons) -> False

We discussed this on the mailing list back in October:
https://mail.scipy.org/pipermail/numpy-discussion/2015-October/073968.html

This PR still needs a release note and probably some clean up on the tests -- the style I used in test_datetime.py (adding assert_array_equiv) is a little unusual.

CC @PythonCHB @jreback @mwiebe

@shoyer
Copy link
Member Author

shoyer commented Jan 13, 2016

There are a couple of tests in test_multiarray that are failing -- they need an update to use a routine like assert_array_equiv, too.

@jreback
Copy link

jreback commented Jan 13, 2016

👍 lgtm

assert_array_compare(lambda x, y: (x == y) | ((x != x) & (y != y)),
x, y, err_msg=err_msg, verbose=verbose,
header='Arrays are not equivalent')

Copy link
Member

Choose a reason for hiding this comment

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

It would probably be better not to introduce a new method like assert_array_equiv, and rather use the assert_array_equal that's already defined in numpy.testing?

def assert_array_equal(x, y, err_msg='', verbose=True):

It probably needs to be updated to handle this NaT change.

Copy link
Member Author

Choose a reason for hiding this comment

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

I would agree, but assert_array_equal already defines the opposite for NaN. My guess is that changing assert_array_equal on NaN would break existing tests, but I also don't want to introduce a new inconsistency between NaN and NaT -- that's what I'm trying to fix here! This suggests that the safest path forward is to add a new testing function.

On Wed, Jan 13, 2016 at 9:09 AM, Mark Wiebe [email protected]
wrote:

@@ -20,6 +21,18 @@
_has_pytz = False

+def assert_array_equiv(x, y, err_msg='', verbose=True):

  • """
  • Raises an AssertionError if two array_like objects are not equivalent.
  • Equivalent objects are either equal or each NaN/NaT in each position.
  • """
  • assert_array_compare(lambda x, y: (x == y) | ((x != x) & (y != y)),
  •                     x, y, err_msg=err_msg, verbose=verbose,
    
  •                     header='Arrays are not equivalent')
    

    It would probably be better not to introduce a new method like assert_array_equiv, and rather use the assert_array_equal that's already defined in numpy.testing?
    def assert_array_equal(x, y, err_msg='', verbose=True):

    It probably needs to be updated to handle this NaT change.

    Reply to this email directly or view it on GitHub:
    https://github.com/numpy/numpy/pull/7001/files#r49618874

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 show me what "the opposite for NaN" means? I thought it was the same behavior:

In [3]: import numpy as np

In [4]: np.testing.assert_array_equal([np.nan], [np.nan])

In [5]: np.testing.assert_array_equal([np.nan], [3])
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)

Copy link
Member Author

Choose a reason for hiding this comment

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

I am mistaken!

I will certainly update assert_array_equal instead :)

@shoyer shoyer force-pushed the NaT-comparison branch 2 times, most recently from 68aae57 to 6fcfb39 Compare January 13, 2016 19:14
@shoyer
Copy link
Member Author

shoyer commented Jan 13, 2016

Per @mwiebe's advice, I fixed up assert_equal and assert_array_equal to handle NaTcomparisons properly instead of adding new testing API.

@charris
Copy link
Member

charris commented Jan 13, 2016

Tests are failing. So, when you make the fixes might as well use the prefix TST, ENH:

@shoyer
Copy link
Member Author

shoyer commented Jan 13, 2016

Oops, let's see how Travis likes this now...

I did not realize we used the TST prefix for test suite enhancements, but I suppose it makes sense -- I did adjust some tests here.

@@ -343,16 +343,27 @@ def assert_equal(actual,desired,err_msg='',verbose=True):
except AssertionError:
raise AssertionError(msg)

def isnat(x):
return (hasattr(x, 'dtype')
and getattr(x.dtype, 'kind', None) in 'mM'
Copy link
Member

Choose a reason for hiding this comment

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

So all dtypes do not have a kind attribute? That's new to me, how does it happen?

Copy link
Member Author

Choose a reason for hiding this comment

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

Here's an example of a failing test:

======================================================================
ERROR: test_api.test_array_astype
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/travis/build/numpy/numpy/builds/venv/lib/python3.4/site-packages/nose/case.py", line 198, in runTest
    self.test(*self.arg)
  File "/home/travis/build/numpy/numpy/builds/venv/lib/python3.4/site-packages/numpy/core/tests/test_api.py", line 234, in test_array_astype
    assert_equal(type(b), np.matrix)
  File "/home/travis/build/numpy/numpy/builds/venv/lib/python3.4/site-packages/numpy/testing/utils.py", line 356, in assert_equal
    if isnat(desired) and isnat(actual):
  File "/home/travis/build/numpy/numpy/builds/venv/lib/python3.4/site-packages/numpy/testing/utils.py", line 347, in isnat
    return hasattr(x, 'dtype') and x.dtype.kind in 'mM' and x != x
AttributeError: 'getset_descriptor' object has no attribute 'kind'

Copy link
Member

Choose a reason for hiding this comment

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

None is dangerous, it will raise an error with the string 'mM'. Using another string would work, say '_'.

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch

@charris
Copy link
Member

charris commented Jan 13, 2016

The prefixes are not always a good fit. The original use was for figuring out what to backport back when we were using svn.

@shoyer shoyer force-pushed the NaT-comparison branch 2 times, most recently from e06ca3a to 1d430c0 Compare January 13, 2016 21:45
@shoyer
Copy link
Member Author

shoyer commented Jan 13, 2016

This is passing now.

Assuming we can get #6453 in for 1.11 as well, I'll a note about this change to the docs from that PR.

# Inf/nan/negative zero handling
try:
# isscalar test to check cases such as [np.nan] != np.nan
if isscalar(desired) != isscalar(actual):
if (isscalar(desired) != isscalar(actual)
and not (isinstance(desired, dtype)
Copy link
Member

Choose a reason for hiding this comment

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

Bit curious as to why dtype needs to be checked.

Copy link
Member Author

Choose a reason for hiding this comment

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

There are some masked array specific tests that use assert_equals to compare a dtype and the string version of a dtype (e.g., "float"). A string is a scalar, but a dtype is not.

On Wed, Jan 13, 2016 at 3:57 PM, Charles Harris [email protected]
wrote:

 # Inf/nan/negative zero handling
 try:
     # isscalar test to check cases such as [np.nan] != np.nan

Copy link
Member Author

Choose a reason for hiding this comment

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

added a comment

@charris
Copy link
Member

charris commented Jan 13, 2016

Looking good. Could you add some tests in numpy/testing/tests/test_utils.py?

@shoyer
Copy link
Member Author

shoyer commented Jan 14, 2016

Added tests to test_utils for the fixed testing routines

@shoyer
Copy link
Member Author

shoyer commented Jan 14, 2016

Tests were failing due to my other recently merged datetime64 bug fix -- should be fixed now.

raise AssertionError(msg)
return
return utils.assert_equal(actual, desired)
# msg = build_err_msg([actual, desired], err_msg,)
Copy link
Contributor

Choose a reason for hiding this comment

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

Why leave the commented out code here?

Copy link
Member Author

Choose a reason for hiding this comment

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

good catch -- removed

td_other = np.timedelta64(1, 'h')
for op in [np.equal, np.less, np.less_equal,
np.greater, np.greater_equal]:
assert not op(dt_nat, dt_nat)
Copy link
Member

Choose a reason for hiding this comment

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

Umm, use assert_ from numpy.testing. Plain old assert goes away when Python is run optimized.

Copy link
Member

Choose a reason for hiding this comment

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

Sorry I missed that earlier.

Copy link
Member Author

Choose a reason for hiding this comment

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

will do... I would be surprised if anyone is running our test suite with runtime optimized python though :)

Copy link
Member Author

Choose a reason for hiding this comment

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

updated

Copy link
Member

Choose a reason for hiding this comment

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

Windows Python used to do so by default, I don't know if it still does.

Now, NaT compares like NaN:
- NaT != NaT -> True
- NaT == NaT (and all other comparisons) -> False

We discussed this on the mailing list back in October:
https://mail.scipy.org/pipermail/numpy-discussion/2015-October/073968.html
charris added a commit that referenced this pull request Jan 14, 2016
API: make all comparisons with NaT false
@charris charris merged commit 7141f40 into numpy:master Jan 14, 2016
@charris
Copy link
Member

charris commented Jan 14, 2016

Thanks Stephan.

@shoyer shoyer deleted the NaT-comparison branch January 14, 2016 23:37
charris added a commit to charris/numpy that referenced this pull request Jan 17, 2016
This reverts commit 7141f40,
reversing changes made to 8fa6e3b.

The original broke some pandas tests. The current plan to get this
in is

* reversion
* issue FutureWarning in 1.11 and 1.12
* make the change in 1.13.
charris added a commit that referenced this pull request Jan 17, 2016
Revert "Merge pull request #7001 from shoyer/NaT-comparison"
@seberg
Copy link
Member

seberg commented Jan 28, 2016

@shoyer, all. The current version has the problem of giving spurious FutureWarnings in the test suit/printing that were fixed here, but were removed agian during revert. I noticed when I tried to get my warning cleanup stuff further (with the idea of removing as many global warnings as possible).

It would be good to have an np.isnat function or include it into np.isnan, but IIRC there was a problem with that? One can fix these changes here also with view('i8') stuff.

Wanted to note this, we can maybe ignore the spurious warnings for 1.12?!

jaimefrio pushed a commit to jaimefrio/numpy that referenced this pull request Mar 22, 2016
This reverts commit 7141f40,
reversing changes made to 8fa6e3b.

The original broke some pandas tests. The current plan to get this
in is

* reversion
* issue FutureWarning in 1.11 and 1.12
* make the change in 1.13.
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