|
1 | 1 | # -*- coding: utf-8 -*-
|
2 | 2 | import warnings
|
3 | 3 | from datetime import datetime, timedelta
|
| 4 | +import operator |
4 | 5 |
|
5 | 6 | import pytest
|
6 | 7 |
|
7 | 8 | import numpy as np
|
8 | 9 |
|
9 | 10 | import pandas as pd
|
| 11 | +from pandas.compat.numpy import np_datetime64_compat |
10 | 12 | import pandas.util.testing as tm
|
11 | 13 | from pandas.errors import PerformanceWarning
|
12 | 14 | from pandas import (Timestamp, Timedelta, Series,
|
@@ -41,6 +43,187 @@ def addend(request):
|
41 | 43 | return request.param
|
42 | 44 |
|
43 | 45 |
|
| 46 | +class TestDatetimeIndexComparisons(object): |
| 47 | + # TODO: De-duplicate with test_comparisons_nat below |
| 48 | + def test_dti_cmp_nat(self): |
| 49 | + left = pd.DatetimeIndex([pd.Timestamp('2011-01-01'), pd.NaT, |
| 50 | + pd.Timestamp('2011-01-03')]) |
| 51 | + right = pd.DatetimeIndex([pd.NaT, pd.NaT, pd.Timestamp('2011-01-03')]) |
| 52 | + |
| 53 | + for lhs, rhs in [(left, right), |
| 54 | + (left.astype(object), right.astype(object))]: |
| 55 | + result = rhs == lhs |
| 56 | + expected = np.array([False, False, True]) |
| 57 | + tm.assert_numpy_array_equal(result, expected) |
| 58 | + |
| 59 | + result = lhs != rhs |
| 60 | + expected = np.array([True, True, False]) |
| 61 | + tm.assert_numpy_array_equal(result, expected) |
| 62 | + |
| 63 | + expected = np.array([False, False, False]) |
| 64 | + tm.assert_numpy_array_equal(lhs == pd.NaT, expected) |
| 65 | + tm.assert_numpy_array_equal(pd.NaT == rhs, expected) |
| 66 | + |
| 67 | + expected = np.array([True, True, True]) |
| 68 | + tm.assert_numpy_array_equal(lhs != pd.NaT, expected) |
| 69 | + tm.assert_numpy_array_equal(pd.NaT != lhs, expected) |
| 70 | + |
| 71 | + expected = np.array([False, False, False]) |
| 72 | + tm.assert_numpy_array_equal(lhs < pd.NaT, expected) |
| 73 | + tm.assert_numpy_array_equal(pd.NaT > lhs, expected) |
| 74 | + |
| 75 | + @pytest.mark.parametrize('op', [operator.eq, operator.ne, |
| 76 | + operator.gt, operator.ge, |
| 77 | + operator.lt, operator.le]) |
| 78 | + def test_comparison_tzawareness_compat(self, op): |
| 79 | + # GH#18162 |
| 80 | + dr = pd.date_range('2016-01-01', periods=6) |
| 81 | + dz = dr.tz_localize('US/Pacific') |
| 82 | + |
| 83 | + with pytest.raises(TypeError): |
| 84 | + op(dr, dz) |
| 85 | + with pytest.raises(TypeError): |
| 86 | + op(dr, list(dz)) |
| 87 | + with pytest.raises(TypeError): |
| 88 | + op(dz, dr) |
| 89 | + with pytest.raises(TypeError): |
| 90 | + op(dz, list(dr)) |
| 91 | + |
| 92 | + # Check that there isn't a problem aware-aware and naive-naive do not |
| 93 | + # raise |
| 94 | + assert (dr == dr).all() |
| 95 | + assert (dr == list(dr)).all() |
| 96 | + assert (dz == dz).all() |
| 97 | + assert (dz == list(dz)).all() |
| 98 | + |
| 99 | + # Check comparisons against scalar Timestamps |
| 100 | + ts = pd.Timestamp('2000-03-14 01:59') |
| 101 | + ts_tz = pd.Timestamp('2000-03-14 01:59', tz='Europe/Amsterdam') |
| 102 | + |
| 103 | + assert (dr > ts).all() |
| 104 | + with pytest.raises(TypeError): |
| 105 | + op(dr, ts_tz) |
| 106 | + |
| 107 | + assert (dz > ts_tz).all() |
| 108 | + with pytest.raises(TypeError): |
| 109 | + op(dz, ts) |
| 110 | + |
| 111 | + @pytest.mark.parametrize('op', [operator.eq, operator.ne, |
| 112 | + operator.gt, operator.ge, |
| 113 | + operator.lt, operator.le]) |
| 114 | + def test_nat_comparison_tzawareness(self, op): |
| 115 | + # GH#19276 |
| 116 | + # tzaware DatetimeIndex should not raise when compared to NaT |
| 117 | + dti = pd.DatetimeIndex(['2014-01-01', pd.NaT, '2014-03-01', pd.NaT, |
| 118 | + '2014-05-01', '2014-07-01']) |
| 119 | + expected = np.array([op == operator.ne] * len(dti)) |
| 120 | + result = op(dti, pd.NaT) |
| 121 | + tm.assert_numpy_array_equal(result, expected) |
| 122 | + |
| 123 | + result = op(dti.tz_localize('US/Pacific'), pd.NaT) |
| 124 | + tm.assert_numpy_array_equal(result, expected) |
| 125 | + |
| 126 | + def test_comparisons_coverage(self): |
| 127 | + rng = date_range('1/1/2000', periods=10) |
| 128 | + |
| 129 | + # raise TypeError for now |
| 130 | + pytest.raises(TypeError, rng.__lt__, rng[3].value) |
| 131 | + |
| 132 | + result = rng == list(rng) |
| 133 | + exp = rng == rng |
| 134 | + tm.assert_numpy_array_equal(result, exp) |
| 135 | + |
| 136 | + def test_comparisons_nat(self): |
| 137 | + |
| 138 | + fidx1 = pd.Index([1.0, np.nan, 3.0, np.nan, 5.0, 7.0]) |
| 139 | + fidx2 = pd.Index([2.0, 3.0, np.nan, np.nan, 6.0, 7.0]) |
| 140 | + |
| 141 | + didx1 = pd.DatetimeIndex(['2014-01-01', pd.NaT, '2014-03-01', pd.NaT, |
| 142 | + '2014-05-01', '2014-07-01']) |
| 143 | + didx2 = pd.DatetimeIndex(['2014-02-01', '2014-03-01', pd.NaT, pd.NaT, |
| 144 | + '2014-06-01', '2014-07-01']) |
| 145 | + darr = np.array([np_datetime64_compat('2014-02-01 00:00Z'), |
| 146 | + np_datetime64_compat('2014-03-01 00:00Z'), |
| 147 | + np_datetime64_compat('nat'), np.datetime64('nat'), |
| 148 | + np_datetime64_compat('2014-06-01 00:00Z'), |
| 149 | + np_datetime64_compat('2014-07-01 00:00Z')]) |
| 150 | + |
| 151 | + cases = [(fidx1, fidx2), (didx1, didx2), (didx1, darr)] |
| 152 | + |
| 153 | + # Check pd.NaT is handles as the same as np.nan |
| 154 | + with tm.assert_produces_warning(None): |
| 155 | + for idx1, idx2 in cases: |
| 156 | + |
| 157 | + result = idx1 < idx2 |
| 158 | + expected = np.array([True, False, False, False, True, False]) |
| 159 | + tm.assert_numpy_array_equal(result, expected) |
| 160 | + |
| 161 | + result = idx2 > idx1 |
| 162 | + expected = np.array([True, False, False, False, True, False]) |
| 163 | + tm.assert_numpy_array_equal(result, expected) |
| 164 | + |
| 165 | + result = idx1 <= idx2 |
| 166 | + expected = np.array([True, False, False, False, True, True]) |
| 167 | + tm.assert_numpy_array_equal(result, expected) |
| 168 | + |
| 169 | + result = idx2 >= idx1 |
| 170 | + expected = np.array([True, False, False, False, True, True]) |
| 171 | + tm.assert_numpy_array_equal(result, expected) |
| 172 | + |
| 173 | + result = idx1 == idx2 |
| 174 | + expected = np.array([False, False, False, False, False, True]) |
| 175 | + tm.assert_numpy_array_equal(result, expected) |
| 176 | + |
| 177 | + result = idx1 != idx2 |
| 178 | + expected = np.array([True, True, True, True, True, False]) |
| 179 | + tm.assert_numpy_array_equal(result, expected) |
| 180 | + |
| 181 | + with tm.assert_produces_warning(None): |
| 182 | + for idx1, val in [(fidx1, np.nan), (didx1, pd.NaT)]: |
| 183 | + result = idx1 < val |
| 184 | + expected = np.array([False, False, False, False, False, False]) |
| 185 | + tm.assert_numpy_array_equal(result, expected) |
| 186 | + result = idx1 > val |
| 187 | + tm.assert_numpy_array_equal(result, expected) |
| 188 | + |
| 189 | + result = idx1 <= val |
| 190 | + tm.assert_numpy_array_equal(result, expected) |
| 191 | + result = idx1 >= val |
| 192 | + tm.assert_numpy_array_equal(result, expected) |
| 193 | + |
| 194 | + result = idx1 == val |
| 195 | + tm.assert_numpy_array_equal(result, expected) |
| 196 | + |
| 197 | + result = idx1 != val |
| 198 | + expected = np.array([True, True, True, True, True, True]) |
| 199 | + tm.assert_numpy_array_equal(result, expected) |
| 200 | + |
| 201 | + # Check pd.NaT is handles as the same as np.nan |
| 202 | + with tm.assert_produces_warning(None): |
| 203 | + for idx1, val in [(fidx1, 3), (didx1, datetime(2014, 3, 1))]: |
| 204 | + result = idx1 < val |
| 205 | + expected = np.array([True, False, False, False, False, False]) |
| 206 | + tm.assert_numpy_array_equal(result, expected) |
| 207 | + result = idx1 > val |
| 208 | + expected = np.array([False, False, False, False, True, True]) |
| 209 | + tm.assert_numpy_array_equal(result, expected) |
| 210 | + |
| 211 | + result = idx1 <= val |
| 212 | + expected = np.array([True, False, True, False, False, False]) |
| 213 | + tm.assert_numpy_array_equal(result, expected) |
| 214 | + result = idx1 >= val |
| 215 | + expected = np.array([False, False, True, False, True, True]) |
| 216 | + tm.assert_numpy_array_equal(result, expected) |
| 217 | + |
| 218 | + result = idx1 == val |
| 219 | + expected = np.array([False, False, True, False, False, False]) |
| 220 | + tm.assert_numpy_array_equal(result, expected) |
| 221 | + |
| 222 | + result = idx1 != val |
| 223 | + expected = np.array([True, True, False, True, True, True]) |
| 224 | + tm.assert_numpy_array_equal(result, expected) |
| 225 | + |
| 226 | + |
44 | 227 | class TestDatetimeIndexArithmetic(object):
|
45 | 228 |
|
46 | 229 | def test_dti_add_timestamp_raises(self):
|
|
0 commit comments