Skip to content

Commit 72e520b

Browse files
committed
COMPAT: remove NaT comparison warnings with numpy >= 1.11
1 parent 92b5322 commit 72e520b

File tree

5 files changed

+107
-59
lines changed

5 files changed

+107
-59
lines changed

doc/source/whatsnew/v0.18.1.txt

+1
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,7 @@ Bug Fixes
281281
- Bug in ``.astype()`` of a ``Float64Inde/Int64Index`` to an ``Int64Index`` (:issue:`12881`)
282282
- Bug in roundtripping an integer based index in ``.to_json()/.read_json()`` when ``orient='index'`` (the default) (:issue:`12866`)
283283

284+
- Compat with >= numpy 1.11 for NaT comparions (:issue:`12969`)
284285
- Bug in ``.drop()`` with a non-unique ``MultiIndex``. (:issue:`12701`)
285286
- Bug in ``.concat`` of datetime tz-aware and naive DataFrames (:issue:`12467`)
286287
- Bug in correctly raising a ``ValueError`` in ``.resample(..).fillna(..)`` when passing a non-string (:issue:`12952`)

pandas/indexes/base.py

+11-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
is_iterator, is_categorical_dtype,
2929
_ensure_object, _ensure_int64, is_bool_indexer,
3030
is_list_like, is_bool_dtype,
31-
is_integer_dtype, is_float_dtype)
31+
is_integer_dtype, is_float_dtype,
32+
needs_i8_conversion)
3233
from pandas.core.strings import StringAccessorMixin
3334

3435
from pandas.core.config import get_option
@@ -3068,6 +3069,9 @@ def _evaluate_with_timedelta_like(self, other, op, opstr):
30683069
def _evaluate_with_datetime_like(self, other, op, opstr):
30693070
raise TypeError("can only perform ops with datetime like values")
30703071

3072+
def _evalute_compare(self, op):
3073+
raise base.AbstractMethodError(self)
3074+
30713075
@classmethod
30723076
def _add_comparison_methods(cls):
30733077
""" add in comparison methods """
@@ -3077,6 +3081,12 @@ def _evaluate_compare(self, other):
30773081
if isinstance(other, (np.ndarray, Index, ABCSeries)):
30783082
if other.ndim > 0 and len(self) != len(other):
30793083
raise ValueError('Lengths must match to compare')
3084+
3085+
# we may need to directly compare underlying
3086+
# representations
3087+
if needs_i8_conversion(self) and needs_i8_conversion(other):
3088+
return self._evaluate_compare(other, op)
3089+
30803090
func = getattr(self.values, op)
30813091
result = func(np.asarray(other))
30823092

pandas/tests/test_lib.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ def test_isscalar_numpy_array_scalars(self):
223223
def test_isscalar_numpy_zerodim_arrays(self):
224224
for zerodim in [np.array(1), np.array('foobar'),
225225
np.array(np.datetime64('2014-01-01')),
226-
np.array(np.timedelta64(1, 'h'))]:
226+
np.array(np.timedelta64(1, 'h')),
227+
np.array(np.datetime64('NaT'))]:
227228
self.assertFalse(lib.isscalar(zerodim))
228229
self.assertTrue(lib.isscalar(lib.item_from_zerodim(zerodim)))
229230

pandas/tseries/base.py

+34-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
from pandas import compat
99
import numpy as np
1010
from pandas.core import common as com, algorithms
11-
from pandas.core.common import is_integer, is_float, AbstractMethodError
11+
from pandas.core.common import (is_integer, is_float, is_bool_dtype,
12+
AbstractMethodError)
1213
import pandas.formats.printing as printing
1314
import pandas.tslib as tslib
1415
import pandas.lib as lib
@@ -124,6 +125,38 @@ def wrapper(left, right):
124125

125126
return wrapper
126127

128+
def _evaluate_compare(self, other, op):
129+
"""
130+
We have been called because a comparison between
131+
8 aware arrays. numpy >= 1.11 will
132+
now warn about NaT comparisons
133+
"""
134+
135+
# coerce to a similar object
136+
if not isinstance(other, type(self)):
137+
if not com.is_list_like(other):
138+
# scalar
139+
other = [other]
140+
elif lib.isscalar(lib.item_from_zerodim(other)):
141+
# ndarray scalar
142+
other = [other.item()]
143+
other = type(self)(other)
144+
145+
# compare
146+
result = getattr(self.asi8, op)(other.asi8)
147+
148+
# technically we could support bool dtyped Index
149+
# for now just return the indexing array directly
150+
mask = (self._isnan) | (other._isnan)
151+
if is_bool_dtype(result):
152+
result[mask] = False
153+
return result
154+
try:
155+
result[mask] = tslib.iNaT
156+
return Index(result)
157+
except TypeError:
158+
return result
159+
127160
@property
128161
def _box_func(self):
129162
"""

pandas/tseries/tests/test_timeseries.py

+59-56
Original file line numberDiff line numberDiff line change
@@ -2532,74 +2532,77 @@ def test_comparisons_nat(self):
25322532
cases = [(fidx1, fidx2), (didx1, didx2), (didx1, darr)]
25332533

25342534
# Check pd.NaT is handles as the same as np.nan
2535-
for idx1, idx2 in cases:
2535+
with tm.assert_produces_warning(None):
2536+
for idx1, idx2 in cases:
25362537

2537-
result = idx1 < idx2
2538-
expected = np.array([True, False, False, False, True, False])
2539-
self.assert_numpy_array_equal(result, expected)
2538+
result = idx1 < idx2
2539+
expected = np.array([True, False, False, False, True, False])
2540+
self.assert_numpy_array_equal(result, expected)
25402541

2541-
result = idx2 > idx1
2542-
expected = np.array([True, False, False, False, True, False])
2543-
self.assert_numpy_array_equal(result, expected)
2542+
result = idx2 > idx1
2543+
expected = np.array([True, False, False, False, True, False])
2544+
self.assert_numpy_array_equal(result, expected)
25442545

2545-
result = idx1 <= idx2
2546-
expected = np.array([True, False, False, False, True, True])
2547-
self.assert_numpy_array_equal(result, expected)
2546+
result = idx1 <= idx2
2547+
expected = np.array([True, False, False, False, True, True])
2548+
self.assert_numpy_array_equal(result, expected)
25482549

2549-
result = idx2 >= idx1
2550-
expected = np.array([True, False, False, False, True, True])
2551-
self.assert_numpy_array_equal(result, expected)
2550+
result = idx2 >= idx1
2551+
expected = np.array([True, False, False, False, True, True])
2552+
self.assert_numpy_array_equal(result, expected)
25522553

2553-
result = idx1 == idx2
2554-
expected = np.array([False, False, False, False, False, True])
2555-
self.assert_numpy_array_equal(result, expected)
2554+
result = idx1 == idx2
2555+
expected = np.array([False, False, False, False, False, True])
2556+
self.assert_numpy_array_equal(result, expected)
25562557

2557-
result = idx1 != idx2
2558-
expected = np.array([True, True, True, True, True, False])
2559-
self.assert_numpy_array_equal(result, expected)
2558+
result = idx1 != idx2
2559+
expected = np.array([True, True, True, True, True, False])
2560+
self.assert_numpy_array_equal(result, expected)
25602561

2561-
for idx1, val in [(fidx1, np.nan), (didx1, pd.NaT)]:
2562-
result = idx1 < val
2563-
expected = np.array([False, False, False, False, False, False])
2564-
self.assert_numpy_array_equal(result, expected)
2565-
result = idx1 > val
2566-
self.assert_numpy_array_equal(result, expected)
2562+
with tm.assert_produces_warning(None):
2563+
for idx1, val in [(fidx1, np.nan), (didx1, pd.NaT)]:
2564+
result = idx1 < val
2565+
expected = np.array([False, False, False, False, False, False])
2566+
self.assert_numpy_array_equal(result, expected)
2567+
result = idx1 > val
2568+
self.assert_numpy_array_equal(result, expected)
25672569

2568-
result = idx1 <= val
2569-
self.assert_numpy_array_equal(result, expected)
2570-
result = idx1 >= val
2571-
self.assert_numpy_array_equal(result, expected)
2570+
result = idx1 <= val
2571+
self.assert_numpy_array_equal(result, expected)
2572+
result = idx1 >= val
2573+
self.assert_numpy_array_equal(result, expected)
25722574

2573-
result = idx1 == val
2574-
self.assert_numpy_array_equal(result, expected)
2575+
result = idx1 == val
2576+
self.assert_numpy_array_equal(result, expected)
25752577

2576-
result = idx1 != val
2577-
expected = np.array([True, True, True, True, True, True])
2578-
self.assert_numpy_array_equal(result, expected)
2578+
result = idx1 != val
2579+
expected = np.array([True, True, True, True, True, True])
2580+
self.assert_numpy_array_equal(result, expected)
25792581

25802582
# Check pd.NaT is handles as the same as np.nan
2581-
for idx1, val in [(fidx1, 3), (didx1, datetime(2014, 3, 1))]:
2582-
result = idx1 < val
2583-
expected = np.array([True, False, False, False, False, False])
2584-
self.assert_numpy_array_equal(result, expected)
2585-
result = idx1 > val
2586-
expected = np.array([False, False, False, False, True, True])
2587-
self.assert_numpy_array_equal(result, expected)
2588-
2589-
result = idx1 <= val
2590-
expected = np.array([True, False, True, False, False, False])
2591-
self.assert_numpy_array_equal(result, expected)
2592-
result = idx1 >= val
2593-
expected = np.array([False, False, True, False, True, True])
2594-
self.assert_numpy_array_equal(result, expected)
2595-
2596-
result = idx1 == val
2597-
expected = np.array([False, False, True, False, False, False])
2598-
self.assert_numpy_array_equal(result, expected)
2599-
2600-
result = idx1 != val
2601-
expected = np.array([True, True, False, True, True, True])
2602-
self.assert_numpy_array_equal(result, expected)
2583+
with tm.assert_produces_warning(None):
2584+
for idx1, val in [(fidx1, 3), (didx1, datetime(2014, 3, 1))]:
2585+
result = idx1 < val
2586+
expected = np.array([True, False, False, False, False, False])
2587+
self.assert_numpy_array_equal(result, expected)
2588+
result = idx1 > val
2589+
expected = np.array([False, False, False, False, True, True])
2590+
self.assert_numpy_array_equal(result, expected)
2591+
2592+
result = idx1 <= val
2593+
expected = np.array([True, False, True, False, False, False])
2594+
self.assert_numpy_array_equal(result, expected)
2595+
result = idx1 >= val
2596+
expected = np.array([False, False, True, False, True, True])
2597+
self.assert_numpy_array_equal(result, expected)
2598+
2599+
result = idx1 == val
2600+
expected = np.array([False, False, True, False, False, False])
2601+
self.assert_numpy_array_equal(result, expected)
2602+
2603+
result = idx1 != val
2604+
expected = np.array([True, True, False, True, True, True])
2605+
self.assert_numpy_array_equal(result, expected)
26032606

26042607
def test_map(self):
26052608
rng = date_range('1/1/2000', periods=10)

0 commit comments

Comments
 (0)