diff --git a/doc/source/whatsnew/v0.18.2.txt b/doc/source/whatsnew/v0.18.2.txt index 6db628417f38e..5b72afe53e30e 100644 --- a/doc/source/whatsnew/v0.18.2.txt +++ b/doc/source/whatsnew/v0.18.2.txt @@ -149,4 +149,5 @@ Bug Fixes - Bug in ``NaT`` - ``Period`` raises ``AttributeError`` (:issue:`13071`) - Bug in ``Period`` addition raises ``TypeError`` if ``Period`` is on right hand side (:issue:`13069`) +- Bug in ``Peirod`` and ``Series`` or ``Index`` comparison raises ``TypeError`` (:issue:`13200`) - Bug in ``pd.set_eng_float_format()`` that would prevent NaN's from formatting (:issue:`11981`) diff --git a/pandas/src/period.pyx b/pandas/src/period.pyx index 0cb0b575b25dc..670fe1e4f168c 100644 --- a/pandas/src/period.pyx +++ b/pandas/src/period.pyx @@ -772,6 +772,9 @@ cdef class Period(object): if self.ordinal == tslib.iNaT or other.ordinal == tslib.iNaT: return _nat_scalar_rules[op] return PyObject_RichCompareBool(self.ordinal, other.ordinal, op) + # index/series like + elif hasattr(other, '_typ'): + return NotImplemented else: if op == Py_EQ: return NotImplemented diff --git a/pandas/tseries/tests/test_period.py b/pandas/tseries/tests/test_period.py index 4217cc9a299a3..db1572a49a9ff 100644 --- a/pandas/tseries/tests/test_period.py +++ b/pandas/tseries/tests/test_period.py @@ -3950,24 +3950,30 @@ def test_pi_pi_comp(self): exp = np.array([False, True, False, False]) self.assert_numpy_array_equal(base == p, exp) + self.assert_numpy_array_equal(p == base, exp) exp = np.array([True, False, True, True]) self.assert_numpy_array_equal(base != p, exp) + self.assert_numpy_array_equal(p != base, exp) exp = np.array([False, False, True, True]) self.assert_numpy_array_equal(base > p, exp) + self.assert_numpy_array_equal(p < base, exp) exp = np.array([True, False, False, False]) self.assert_numpy_array_equal(base < p, exp) + self.assert_numpy_array_equal(p > base, exp) exp = np.array([False, True, True, True]) self.assert_numpy_array_equal(base >= p, exp) + self.assert_numpy_array_equal(p <= base, exp) exp = np.array([True, True, False, False]) self.assert_numpy_array_equal(base <= p, exp) + self.assert_numpy_array_equal(p >= base, exp) - idx = PeriodIndex( - ['2011-02', '2011-01', '2011-03', '2011-05'], freq=freq) + idx = PeriodIndex(['2011-02', '2011-01', '2011-03', + '2011-05'], freq=freq) exp = np.array([False, False, True, False]) self.assert_numpy_array_equal(base == idx, exp) @@ -3992,6 +3998,9 @@ def test_pi_pi_comp(self): with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): base <= Period('2011', freq='A') + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + Period('2011', freq='A') >= base + with tm.assertRaisesRegexp(ValueError, msg): idx = PeriodIndex(['2011', '2012', '2013', '2014'], freq='A') base <= idx @@ -4001,6 +4010,9 @@ def test_pi_pi_comp(self): with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): base <= Period('2011', freq='4M') + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + Period('2011', freq='4M') >= base + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): idx = PeriodIndex(['2011', '2012', '2013', '2014'], freq='4M') base <= idx @@ -4013,17 +4025,23 @@ def test_pi_nat_comp(self): result = idx1 > Period('2011-02', freq=freq) exp = np.array([False, False, False, True]) self.assert_numpy_array_equal(result, exp) + result = Period('2011-02', freq=freq) < idx1 + self.assert_numpy_array_equal(result, exp) result = idx1 == Period('NaT', freq=freq) exp = np.array([False, False, False, False]) self.assert_numpy_array_equal(result, exp) + result = Period('NaT', freq=freq) == idx1 + self.assert_numpy_array_equal(result, exp) result = idx1 != Period('NaT', freq=freq) exp = np.array([True, True, True, True]) self.assert_numpy_array_equal(result, exp) + result = Period('NaT', freq=freq) != idx1 + self.assert_numpy_array_equal(result, exp) - idx2 = PeriodIndex( - ['2011-02', '2011-01', '2011-04', 'NaT'], freq=freq) + idx2 = PeriodIndex(['2011-02', '2011-01', '2011-04', + 'NaT'], freq=freq) result = idx1 < idx2 exp = np.array([True, False, False, False]) self.assert_numpy_array_equal(result, exp) @@ -4044,11 +4062,12 @@ def test_pi_nat_comp(self): exp = np.array([False, False, True, False]) self.assert_numpy_array_equal(result, exp) - diff = PeriodIndex( - ['2011-02', '2011-01', '2011-04', 'NaT'], freq='4M') + diff = PeriodIndex(['2011-02', '2011-01', '2011-04', + 'NaT'], freq='4M') msg = "Input has different freq=4M from PeriodIndex" with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): idx1 > diff + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): idx1 == diff @@ -4185,6 +4204,106 @@ def test_ops_series_period(self): tm.assert_series_equal(s2 - s, exp) tm.assert_series_equal(s - s2, -exp) + def test_comp_series_period_scalar(self): + # GH 13200 + for freq in ['M', '2M', '3M']: + base = Series([Period(x, freq=freq) for x in + ['2011-01', '2011-02', '2011-03', '2011-04']]) + p = Period('2011-02', freq=freq) + + exp = pd.Series([False, True, False, False]) + tm.assert_series_equal(base == p, exp) + tm.assert_series_equal(p == base, exp) + + exp = pd.Series([True, False, True, True]) + tm.assert_series_equal(base != p, exp) + tm.assert_series_equal(p != base, exp) + + exp = pd.Series([False, False, True, True]) + tm.assert_series_equal(base > p, exp) + tm.assert_series_equal(p < base, exp) + + exp = pd.Series([True, False, False, False]) + tm.assert_series_equal(base < p, exp) + tm.assert_series_equal(p > base, exp) + + exp = pd.Series([False, True, True, True]) + tm.assert_series_equal(base >= p, exp) + tm.assert_series_equal(p <= base, exp) + + exp = pd.Series([True, True, False, False]) + tm.assert_series_equal(base <= p, exp) + tm.assert_series_equal(p >= base, exp) + + # different base freq + msg = "Input has different freq=A-DEC from Period" + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + base <= Period('2011', freq='A') + + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + Period('2011', freq='A') >= base + + def test_comp_series_period_series(self): + # GH 13200 + for freq in ['M', '2M', '3M']: + base = Series([Period(x, freq=freq) for x in + ['2011-01', '2011-02', '2011-03', '2011-04']]) + + s = Series([Period(x, freq=freq) for x in + ['2011-02', '2011-01', '2011-03', '2011-05']]) + + exp = Series([False, False, True, False]) + tm.assert_series_equal(base == s, exp) + + exp = Series([True, True, False, True]) + tm.assert_series_equal(base != s, exp) + + exp = Series([False, True, False, False]) + tm.assert_series_equal(base > s, exp) + + exp = Series([True, False, False, True]) + tm.assert_series_equal(base < s, exp) + + exp = Series([False, True, True, False]) + tm.assert_series_equal(base >= s, exp) + + exp = Series([True, False, True, True]) + tm.assert_series_equal(base <= s, exp) + + s2 = Series([Period(x, freq='A') for x in + ['2011', '2011', '2011', '2011']]) + + # different base freq + msg = "Input has different freq=A-DEC from Period" + with tm.assertRaisesRegexp(period.IncompatibleFrequency, msg): + base <= s2 + + def test_comp_series_period_object(self): + # GH 13200 + base = Series([Period('2011', freq='A'), Period('2011-02', freq='M'), + Period('2013', freq='A'), Period('2011-04', freq='M')]) + + s = Series([Period('2012', freq='A'), Period('2011-01', freq='M'), + Period('2013', freq='A'), Period('2011-05', freq='M')]) + + exp = Series([False, False, True, False]) + tm.assert_series_equal(base == s, exp) + + exp = Series([True, True, False, True]) + tm.assert_series_equal(base != s, exp) + + exp = Series([False, True, False, False]) + tm.assert_series_equal(base > s, exp) + + exp = Series([True, False, False, True]) + tm.assert_series_equal(base < s, exp) + + exp = Series([False, True, True, False]) + tm.assert_series_equal(base >= s, exp) + + exp = Series([True, False, True, True]) + tm.assert_series_equal(base <= s, exp) + def test_ops_frame_period(self): # GH 13043 df = pd.DataFrame({'A': [pd.Period('2015-01', freq='M'),