From b3fefa340c7fa36a87641c716d6419b9c0b66ded Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Tue, 30 Jan 2018 17:16:37 -0800 Subject: [PATCH 1/7] move Series[Period] tests to tests.series.test_arithmetic --- pandas/tests/series/test_arithmetic.py | 121 +++++++++++++++++++++++++ pandas/tests/series/test_period.py | 116 +----------------------- 2 files changed, 122 insertions(+), 115 deletions(-) diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index ca558dd6b7cd5..f08626a9a006e 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -3,6 +3,9 @@ import operator import numpy as np +import pytest + +from pandas._libs.tslibs.period import IncompatibleFrequency import pandas as pd import pandas.util.testing as tm @@ -81,6 +84,124 @@ def test_compare_timedelta_series(self): tm.assert_series_equal(actual, expected) +class TestPeriodSeriesComparisons(object): + def test_series_comparison_scalars(self): + ser = pd.Series(pd.period_range('2000-01-01', periods=10, freq='D')) + val = pd.Period('2000-01-04', freq='D') + result = ser > val + expected = pd.Series([x > val for x in ser]) + tm.assert_series_equal(result, expected) + + val = ser[5] + result = ser > val + expected = pd.Series([x > val for x in ser]) + tm.assert_series_equal(result, expected) + + @pytest.mark.paramtrize('freq', ['M', '2M', '3M']) + def test_comp_series_period_scalar(self, freq): + # GH 13200 + base = pd.Series([pd.Period(x, freq=freq) for x in + ['2011-01', '2011-02', '2011-03', '2011-04']]) + p = pd.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.assert_raises_regex(IncompatibleFrequency, msg): + base <= pd.Period('2011', freq='A') + + with tm.assert_raises_regex(IncompatibleFrequency, msg): + pd.Period('2011', freq='A') >= base + + @pytest.mark.paramtrize('freq', ['M', '2M', '3M']) + def test_cmp_series_period_series(self, freq): + # GH#13200 + base = pd.Series([pd.Period(x, freq=freq) for x in + ['2011-01', '2011-02', '2011-03', '2011-04']]) + + ser = pd.Series([pd.Period(x, freq=freq) for x in + ['2011-02', '2011-01', '2011-03', '2011-05']]) + + exp = pd.Series([False, False, True, False]) + tm.assert_series_equal(base == ser, exp) + + exp = pd.Series([True, True, False, True]) + tm.assert_series_equal(base != ser, exp) + + exp = pd.Series([False, True, False, False]) + tm.assert_series_equal(base > ser, exp) + + exp = pd.Series([True, False, False, True]) + tm.assert_series_equal(base < ser, exp) + + exp = pd.Series([False, True, True, False]) + tm.assert_series_equal(base >= ser, exp) + + exp = pd.Series([True, False, True, True]) + tm.assert_series_equal(base <= ser, exp) + + ser2 = pd.Series([pd.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.assert_raises_regex(IncompatibleFrequency, msg): + base <= ser2 + + def test_cmp_series_period_object(self): + # GH#13200 + base = pd.Series([pd.Period('2011', freq='A'), + pd.Period('2011-02', freq='M'), + pd.Period('2013', freq='A'), + pd.Period('2011-04', freq='M')]) + + ser = pd.Series([pd.Period('2012', freq='A'), + pd.Period('2011-01', freq='M'), + pd.Period('2013', freq='A'), + pd.Period('2011-05', freq='M')]) + + exp = pd.Series([False, False, True, False]) + tm.assert_series_equal(base == ser, exp) + + exp = pd.Series([True, True, False, True]) + tm.assert_series_equal(base != ser, exp) + + exp = pd.Series([False, True, False, False]) + tm.assert_series_equal(base > ser, exp) + + exp = pd.Series([True, False, False, True]) + tm.assert_series_equal(base < ser, exp) + + exp = pd.Series([False, True, True, False]) + tm.assert_series_equal(base >= ser, exp) + + exp = pd.Series([True, False, True, True]) + tm.assert_series_equal(base <= ser, exp) + + class TestPeriodSeriesArithmetic(object): def test_ops_series_timedelta(self): # GH 13043 diff --git a/pandas/tests/series/test_period.py b/pandas/tests/series/test_period.py index 9d5ef5e51ff20..8ff2071e351d0 100644 --- a/pandas/tests/series/test_period.py +++ b/pandas/tests/series/test_period.py @@ -3,7 +3,7 @@ import pandas as pd import pandas.util.testing as tm import pandas.core.indexes.period as period -from pandas import Series, period_range, DataFrame, Period +from pandas import Series, period_range, DataFrame def _permute(obj): @@ -63,17 +63,6 @@ def test_dropna(self): tm.assert_series_equal(s.dropna(), Series([pd.Period('2011-01', freq='M')])) - def test_series_comparison_scalars(self): - val = pd.Period('2000-01-04', freq='D') - result = self.series > val - expected = pd.Series([x > val for x in self.series]) - tm.assert_series_equal(result, expected) - - val = self.series[5] - result = self.series > val - expected = pd.Series([x > val for x in self.series]) - tm.assert_series_equal(result, expected) - def test_between(self): left, right = self.series[[2, 7]] result = self.series.between(left, right) @@ -128,109 +117,6 @@ def test_intercept_astype_object(self): result = df.values.squeeze() assert (result[:, 0] == expected.values).all() - 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.assert_raises_regex( - period.IncompatibleFrequency, msg): - base <= Period('2011', freq='A') - - with tm.assert_raises_regex( - 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.assert_raises_regex( - 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_align_series(self): rng = period_range('1/1/2000', '1/1/2010', freq='A') ts = Series(np.random.randn(len(rng)), index=rng) From b0dd2151b4d5710c32ffb363e5bd1ed27bd3930c Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Tue, 30 Jan 2018 17:25:18 -0800 Subject: [PATCH 2/7] move arithmetic tests to tests.series.test_arithmetic --- pandas/tests/series/test_arithmetic.py | 113 ++++++++++++-------- pandas/tests/series/test_datetime_values.py | 11 +- pandas/tests/series/test_operators.py | 14 --- 3 files changed, 71 insertions(+), 67 deletions(-) diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index f08626a9a006e..2a969835b83f4 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -from datetime import timedelta +from datetime import datetime, timedelta import operator import numpy as np import pytest +from pandas import Series, Timestamp, Period from pandas._libs.tslibs.period import IncompatibleFrequency import pandas as pd @@ -20,6 +21,25 @@ def test_compare_invalid(self): b.name = pd.Timestamp('2000-01-01') tm.assert_series_equal(a / b, 1 / (b / a)) + @pytest.mark.parametrize('opname', ['eq', 'ne', 'gt', 'lt', 'ge', 'le']) + def test_return_dtypes_flex_cmp_constant(self, opname): + # GH#15115 + ser = Series([1, 3, 2], index=range(3)) + const = 2 + + result = getattr(ser, opname)(const).get_dtype_counts() + tm.assert_series_equal(result, Series([1], ['bool'])) + + @pytest.mark.parametrize('opname', ['eq', 'ne', 'gt', 'lt', 'ge', 'le']) + def test_return_dtypes_flex_cmp_empty(self, opname): + # GH#15115 empty Series case + ser = Series([1, 3, 2], index=range(3)) + empty = ser.iloc[:0] + const = 2 + + result = getattr(empty, opname)(const).get_dtype_counts() + tm.assert_series_equal(result, Series([1], ['bool'])) + class TestTimestampSeriesComparison(object): def test_timestamp_compare_series(self): @@ -86,119 +106,119 @@ def test_compare_timedelta_series(self): class TestPeriodSeriesComparisons(object): def test_series_comparison_scalars(self): - ser = pd.Series(pd.period_range('2000-01-01', periods=10, freq='D')) - val = pd.Period('2000-01-04', freq='D') + ser = Series(pd.period_range('2000-01-01', periods=10, freq='D')) + val = Period('2000-01-04', freq='D') result = ser > val - expected = pd.Series([x > val for x in ser]) + expected = Series([x > val for x in ser]) tm.assert_series_equal(result, expected) val = ser[5] result = ser > val - expected = pd.Series([x > val for x in ser]) + expected = Series([x > val for x in ser]) tm.assert_series_equal(result, expected) @pytest.mark.paramtrize('freq', ['M', '2M', '3M']) def test_comp_series_period_scalar(self, freq): # GH 13200 - base = pd.Series([pd.Period(x, freq=freq) for x in - ['2011-01', '2011-02', '2011-03', '2011-04']]) - p = pd.Period('2011-02', freq=freq) + 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]) + exp = 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]) + exp = 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]) + exp = 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]) + exp = 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]) + exp = 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]) + exp = 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.assert_raises_regex(IncompatibleFrequency, msg): - base <= pd.Period('2011', freq='A') + base <= Period('2011', freq='A') with tm.assert_raises_regex(IncompatibleFrequency, msg): - pd.Period('2011', freq='A') >= base + Period('2011', freq='A') >= base @pytest.mark.paramtrize('freq', ['M', '2M', '3M']) def test_cmp_series_period_series(self, freq): # GH#13200 - base = pd.Series([pd.Period(x, freq=freq) for x in - ['2011-01', '2011-02', '2011-03', '2011-04']]) + base = Series([Period(x, freq=freq) for x in + ['2011-01', '2011-02', '2011-03', '2011-04']]) - ser = pd.Series([pd.Period(x, freq=freq) for x in - ['2011-02', '2011-01', '2011-03', '2011-05']]) + ser = Series([Period(x, freq=freq) for x in + ['2011-02', '2011-01', '2011-03', '2011-05']]) - exp = pd.Series([False, False, True, False]) + exp = Series([False, False, True, False]) tm.assert_series_equal(base == ser, exp) - exp = pd.Series([True, True, False, True]) + exp = Series([True, True, False, True]) tm.assert_series_equal(base != ser, exp) - exp = pd.Series([False, True, False, False]) + exp = Series([False, True, False, False]) tm.assert_series_equal(base > ser, exp) - exp = pd.Series([True, False, False, True]) + exp = Series([True, False, False, True]) tm.assert_series_equal(base < ser, exp) - exp = pd.Series([False, True, True, False]) + exp = Series([False, True, True, False]) tm.assert_series_equal(base >= ser, exp) - exp = pd.Series([True, False, True, True]) + exp = Series([True, False, True, True]) tm.assert_series_equal(base <= ser, exp) - ser2 = pd.Series([pd.Period(x, freq='A') for x in - ['2011', '2011', '2011', '2011']]) + ser2 = 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.assert_raises_regex(IncompatibleFrequency, msg): base <= ser2 - def test_cmp_series_period_object(self): + def test_cmp_series_period_scalar(self): # GH#13200 - base = pd.Series([pd.Period('2011', freq='A'), - pd.Period('2011-02', freq='M'), - pd.Period('2013', freq='A'), - pd.Period('2011-04', freq='M')]) + base = Series([Period('2011', freq='A'), + Period('2011-02', freq='M'), + Period('2013', freq='A'), + Period('2011-04', freq='M')]) - ser = pd.Series([pd.Period('2012', freq='A'), - pd.Period('2011-01', freq='M'), - pd.Period('2013', freq='A'), - pd.Period('2011-05', freq='M')]) + ser = Series([Period('2012', freq='A'), + Period('2011-01', freq='M'), + Period('2013', freq='A'), + Period('2011-05', freq='M')]) - exp = pd.Series([False, False, True, False]) + exp = Series([False, False, True, False]) tm.assert_series_equal(base == ser, exp) - exp = pd.Series([True, True, False, True]) + exp = Series([True, True, False, True]) tm.assert_series_equal(base != ser, exp) - exp = pd.Series([False, True, False, False]) + exp = Series([False, True, False, False]) tm.assert_series_equal(base > ser, exp) - exp = pd.Series([True, False, False, True]) + exp = Series([True, False, False, True]) tm.assert_series_equal(base < ser, exp) - exp = pd.Series([False, True, True, False]) + exp = Series([False, True, True, False]) tm.assert_series_equal(base >= ser, exp) - exp = pd.Series([True, False, True, True]) + exp = Series([True, False, True, True]) tm.assert_series_equal(base <= ser, exp) @@ -255,3 +275,10 @@ def test_timestamp_sub_series(self): np.timedelta64(1, 'D')]) tm.assert_series_equal(ser - ts, delta_series) tm.assert_series_equal(ts - ser, -delta_series) + + def test_dt64ser_sub_datetime_dtype(self): + ts = Timestamp(datetime(1993, 1, 7, 13, 30, 00)) + dt = datetime(1993, 6, 22, 13, 30) + ser = Series([ts]) + result = pd.to_timedelta(np.abs(ser - dt)) + assert result.dtype == 'timedelta64[ns]' diff --git a/pandas/tests/series/test_datetime_values.py b/pandas/tests/series/test_datetime_values.py index b79d8def905af..49b4600b10738 100644 --- a/pandas/tests/series/test_datetime_values.py +++ b/pandas/tests/series/test_datetime_values.py @@ -11,7 +11,7 @@ from pandas.core.dtypes.common import is_integer_dtype, is_list_like from pandas import (Index, Series, DataFrame, bdate_range, date_range, period_range, timedelta_range, - PeriodIndex, Timestamp, DatetimeIndex, TimedeltaIndex) + PeriodIndex, DatetimeIndex, TimedeltaIndex) import pandas.core.common as com from pandas.util.testing import assert_series_equal @@ -377,15 +377,6 @@ def test_dt_accessor_api(self): s.dt assert not hasattr(s, 'dt') - def test_sub_of_datetime_from_TimeSeries(self): - from pandas.core.tools.timedeltas import to_timedelta - from datetime import datetime - a = Timestamp(datetime(1993, 0o1, 0o7, 13, 30, 00)) - b = datetime(1993, 6, 22, 13, 30) - a = Series([a]) - result = to_timedelta(np.abs(a - b)) - assert result.dtype == 'timedelta64[ns]' - def test_between(self): s = Series(bdate_range('1/1/2000', periods=20).astype(object)) s[::2] = np.nan diff --git a/pandas/tests/series/test_operators.py b/pandas/tests/series/test_operators.py index 8feee6e6cff68..99468241deeff 100644 --- a/pandas/tests/series/test_operators.py +++ b/pandas/tests/series/test_operators.py @@ -1817,20 +1817,6 @@ def test_ops_datetimelike_align(self): result = (dt2.to_frame() - dt.to_frame())[0] assert_series_equal(result, expected) - def test_return_dtypes_bool_op_costant(self): - # gh15115 - s = pd.Series([1, 3, 2], index=range(3)) - const = 2 - for op in ['eq', 'ne', 'gt', 'lt', 'ge', 'le']: - result = getattr(s, op)(const).get_dtype_counts() - tm.assert_series_equal(result, Series([1], ['bool'])) - - # empty Series - empty = s.iloc[:0] - for op in ['eq', 'ne', 'gt', 'lt', 'ge', 'le']: - result = getattr(empty, op)(const).get_dtype_counts() - tm.assert_series_equal(result, Series([1], ['bool'])) - def test_operators_bitwise(self): # GH 9016: support bitwise op for integer types index = list('bca') From 305edeae62d19bdc810466abeb8d6e651fef843f Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Tue, 30 Jan 2018 17:31:10 -0800 Subject: [PATCH 3/7] move generic series arith tests --- pandas/tests/series/test_arithmetic.py | 60 ++++++++++++++++++++++++++ pandas/tests/series/test_operators.py | 47 -------------------- 2 files changed, 60 insertions(+), 47 deletions(-) diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index 2a969835b83f4..7683916c7fda4 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -12,6 +12,9 @@ import pandas.util.testing as tm +# ------------------------------------------------------------------ +# Comparisons + class TestSeriesComparison(object): def test_compare_invalid(self): # GH#8058 @@ -221,6 +224,63 @@ def test_cmp_series_period_scalar(self): exp = Series([True, False, True, True]) tm.assert_series_equal(base <= ser, exp) +# ------------------------------------------------------------------ +# Arithmetic + +class TestSeriesArithmetic(object): + # Standard, numeric, or otherwise not-Timestamp/Timedelta/Period dtypes + @pytest.mark.parametrize('data', [ + [1, 2, 3], + [1.1, 2.2, 3.3], + [Timestamp('2011-01-01'), Timestamp('2011-01-02'), pd.NaT], + ['x', 'y', 1]]) + @pytest.mark.parametrize('dtype', [None, object]) + def test_series_radd_str_invalid(self, dtype, data): + ser = Series(data, dtype=dtype) + with pytest.raises(TypeError): + 'foo_' + ser + + # TODO: parametrize, better name + def test_object_ser_add_invalid(self): + # invalid ops + obj_ser = tm.makeObjectSeries() + obj_ser.name = 'objects' + with pytest.raises(Exception): + obj_ser + 1 + with pytest.raises(Exception): + obj_ser + np.array(1, dtype=np.int64) + with pytest.raises(Exception): + obj_ser - 1 + with pytest.raises(Exception): + obj_ser - np.array(1, dtype=np.int64) + + @pytest.mark.parametrize('dtype', [None, object]) + def test_series_with_dtype_radd_nan(self, dtype): + ser = pd.Series([1, 2, 3], dtype=dtype) + expected = pd.Series([np.nan, np.nan, np.nan], dtype=dtype) + + result = np.nan + ser + assert_series_equal(result, expected) + + result = ser + np.nan + assert_series_equal(result, expected) + + @pytest.mark.parametrize('dtype', [None, object]) + def test_series_with_dtype_radd_int(self, dtype): + ser = pd.Series([1, 2, 3], dtype=dtype) + expected = pd.Series([2, 3, 4], dtype=dtype) + + result = 1 + ser + assert_series_equal(result, expected) + + result = ser + 1 + assert_series_equal(result, expected) + + def test_series_radd_str(self): + ser = pd.Series(['x', np.nan, 'x']) + assert_series_equal('a' + ser, pd.Series(['ax', np.nan, 'ax'])) + assert_series_equal(ser + 'a', pd.Series(['xa', np.nan, 'xa'])) + class TestPeriodSeriesArithmetic(object): def test_ops_series_timedelta(self): diff --git a/pandas/tests/series/test_operators.py b/pandas/tests/series/test_operators.py index 99468241deeff..05ccb25960b1f 100644 --- a/pandas/tests/series/test_operators.py +++ b/pandas/tests/series/test_operators.py @@ -1686,15 +1686,6 @@ def test_operators_empty_int_corner(self): s2 = Series({'x': 0.}) assert_series_equal(s1 * s2, Series([np.nan], index=['x'])) - def test_invalid_ops(self): - # invalid ops - pytest.raises(Exception, self.objSeries.__add__, 1) - pytest.raises(Exception, self.objSeries.__add__, - np.array(1, dtype=np.int64)) - pytest.raises(Exception, self.objSeries.__sub__, 1) - pytest.raises(Exception, self.objSeries.__sub__, - np.array(1, dtype=np.int64)) - @pytest.mark.parametrize("m", [1, 3, 10]) @pytest.mark.parametrize("unit", ['D', 'h', 'm', 's', 'ms', 'us', 'ns']) def test_timedelta64_conversions(self, m, unit): @@ -2101,11 +2092,6 @@ def test_series_frame_radd_bug(self): with pytest.raises(TypeError): self.ts + datetime.now() - def test_series_radd_str(self): - ser = pd.Series(['x', np.nan, 'x']) - assert_series_equal('a' + ser, pd.Series(['ax', np.nan, 'ax'])) - assert_series_equal(ser + 'a', pd.Series(['xa', np.nan, 'xa'])) - @pytest.mark.parametrize('dtype', [None, object]) def test_series_with_dtype_radd_timedelta(self, dtype): ser = pd.Series([pd.Timedelta('1 days'), pd.Timedelta('2 days'), @@ -2119,39 +2105,6 @@ def test_series_with_dtype_radd_timedelta(self, dtype): result = ser + pd.Timedelta('3 days') assert_series_equal(result, expected) - @pytest.mark.parametrize('dtype', [None, object]) - def test_series_with_dtype_radd_int(self, dtype): - ser = pd.Series([1, 2, 3], dtype=dtype) - expected = pd.Series([2, 3, 4], dtype=dtype) - - result = 1 + ser - assert_series_equal(result, expected) - - result = ser + 1 - assert_series_equal(result, expected) - - @pytest.mark.parametrize('dtype', [None, object]) - def test_series_with_dtype_radd_nan(self, dtype): - ser = pd.Series([1, 2, 3], dtype=dtype) - expected = pd.Series([np.nan, np.nan, np.nan], dtype=dtype) - - result = np.nan + ser - assert_series_equal(result, expected) - - result = ser + np.nan - assert_series_equal(result, expected) - - @pytest.mark.parametrize('data', [ - [1, 2, 3], - [1.1, 2.2, 3.3], - [pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02'), pd.NaT], - ['x', 'y', 1]]) - @pytest.mark.parametrize('dtype', [None, object]) - def test_series_radd_str_invalid(self, dtype, data): - ser = Series(data, dtype=dtype) - with pytest.raises(TypeError): - 'foo_' + ser - def test_operators_frame(self): # rpow does not work with DataFrame df = DataFrame({'A': self.ts}) From 59e9936725125ef433b9e701ff4eba6f93fd25db Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Tue, 30 Jan 2018 17:40:24 -0800 Subject: [PATCH 4/7] collect Frame arith tests --- pandas/tests/frame/test_arithmetic.py | 56 ++++++++++++++++++++++++++ pandas/tests/frame/test_operators.py | 44 +------------------- pandas/tests/series/test_arithmetic.py | 4 +- 3 files changed, 59 insertions(+), 45 deletions(-) diff --git a/pandas/tests/frame/test_arithmetic.py b/pandas/tests/frame/test_arithmetic.py index 3f4e3877a276a..37bfd8e100f3a 100644 --- a/pandas/tests/frame/test_arithmetic.py +++ b/pandas/tests/frame/test_arithmetic.py @@ -1,11 +1,67 @@ # -*- coding: utf-8 -*- +import pytest import numpy as np import pandas as pd import pandas.util.testing as tm +# ------------------------------------------------------------------- +# Comparisons + +class TestFrameComparisons(object): + def test_df_boolean_comparison_error(self): + # GH#4576 + # boolean comparisons with a tuple/list give unexpected results + df = pd.DataFrame(np.arange(6).reshape((3, 2))) + + # not shape compatible + with pytest.raises(ValueError): + df == (2, 2) + with pytest.raises(ValueError): + df == [2, 2] + + def test_df_float_none_comparison(self): + df = pd.DataFrame(np.random.randn(8, 3), index=range(8), + columns=['A', 'B', 'C']) + + with pytest.raises(TypeError): + df.__eq__(None) + + def test_df_string_comparison(self): + df = pd.DataFrame([{"a": 1, "b": "foo"}, {"a": 2, "b": "bar"}]) + mask_a = df.a > 1 + tm.assert_frame_equal(df[mask_a], df.loc[1:1, :]) + tm.assert_frame_equal(df[-mask_a], df.loc[0:0, :]) + + mask_b = df.b == "foo" + tm.assert_frame_equal(df[mask_b], df.loc[0:0, :]) + tm.assert_frame_equal(df[-mask_b], df.loc[1:1, :]) + + @pytest.mark.parametrize('opname', ['eq', 'ne', 'gt', 'lt', 'ge', 'le']) + def test_df_flex_cmp_constant_return_types(self, opname): + # GH#15077, non-empty DataFrame + df = pd.DataFrame({'x': [1, 2, 3], 'y': [1., 2., 3.]}) + const = 2 + + result = getattr(df, opname)(const).get_dtype_counts() + tm.assert_series_equal(result, pd.Series([2], ['bool'])) + + @pytest.mark.parametrize('opname', ['eq', 'ne', 'gt', 'lt', 'ge', 'le']) + def test_df_flex_cmp_constant_return_types_empty(self, opname): + # GH#15077 empty DataFrame + df = pd.DataFrame({'x': [1, 2, 3], 'y': [1., 2., 3.]}) + const = 2 + + empty = df.iloc[:0] + result = getattr(empty, opname)(const).get_dtype_counts() + tm.assert_series_equal(result, pd.Series([2], ['bool'])) + + +# ------------------------------------------------------------------- +# Arithmetic + class TestPeriodFrameArithmetic(object): def test_ops_frame_period(self): diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index 0bc4a7df6a55b..84420184f776d 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -10,7 +10,7 @@ from numpy import nan, random import numpy as np -from pandas.compat import lrange, range +from pandas.compat import range from pandas import compat from pandas import (DataFrame, Series, MultiIndex, Timestamp, date_range) @@ -714,22 +714,6 @@ def _test_seq(df, idx_ser, col_ser): exp = DataFrame({'col': [False, True, False]}) assert_frame_equal(result, exp) - def test_return_dtypes_bool_op_costant(self): - # GH15077 - df = DataFrame({'x': [1, 2, 3], 'y': [1., 2., 3.]}) - const = 2 - - # not empty DataFrame - for op in ['eq', 'ne', 'gt', 'lt', 'ge', 'le']: - result = getattr(df, op)(const).get_dtype_counts() - tm.assert_series_equal(result, Series([2], ['bool'])) - - # empty DataFrame - empty = df.iloc[:0] - for op in ['eq', 'ne', 'gt', 'lt', 'ge', 'le']: - result = getattr(empty, op)(const).get_dtype_counts() - tm.assert_series_equal(result, Series([2], ['bool'])) - def test_dti_tz_convert_to_utc(self): base = pd.DatetimeIndex(['2011-01-01', '2011-01-02', '2011-01-03'], tz='UTC') @@ -1009,22 +993,6 @@ def test_comparison_protected_from_errstate(self): result = (missing_df < 0).values tm.assert_numpy_array_equal(result, expected) - def test_string_comparison(self): - df = DataFrame([{"a": 1, "b": "foo"}, {"a": 2, "b": "bar"}]) - mask_a = df.a > 1 - assert_frame_equal(df[mask_a], df.loc[1:1, :]) - assert_frame_equal(df[-mask_a], df.loc[0:0, :]) - - mask_b = df.b == "foo" - assert_frame_equal(df[mask_b], df.loc[0:0, :]) - assert_frame_equal(df[-mask_b], df.loc[1:1, :]) - - def test_float_none_comparison(self): - df = DataFrame(np.random.randn(8, 3), index=lrange(8), - columns=['A', 'B', 'C']) - - pytest.raises(TypeError, df.__eq__, None) - def test_boolean_comparison(self): # GH 4576 @@ -1091,16 +1059,6 @@ def test_boolean_comparison(self): result = df == tup assert_frame_equal(result, expected) - def test_boolean_comparison_error(self): - - # GH 4576 - # boolean comparisons with a tuple/list give unexpected results - df = DataFrame(np.arange(6).reshape((3, 2))) - - # not shape compatible - pytest.raises(ValueError, lambda: df == (2, 2)) - pytest.raises(ValueError, lambda: df == [2, 2]) - def test_combine_generic(self): df1 = self.frame df2 = self.frame.loc[self.frame.index[:-5], ['A', 'B', 'C']] diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index 7683916c7fda4..05993afded30a 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -25,7 +25,7 @@ def test_compare_invalid(self): tm.assert_series_equal(a / b, 1 / (b / a)) @pytest.mark.parametrize('opname', ['eq', 'ne', 'gt', 'lt', 'ge', 'le']) - def test_return_dtypes_flex_cmp_constant(self, opname): + def test_ser_flex_cmp_return_dtypes(self, opname): # GH#15115 ser = Series([1, 3, 2], index=range(3)) const = 2 @@ -34,7 +34,7 @@ def test_return_dtypes_flex_cmp_constant(self, opname): tm.assert_series_equal(result, Series([1], ['bool'])) @pytest.mark.parametrize('opname', ['eq', 'ne', 'gt', 'lt', 'ge', 'le']) - def test_return_dtypes_flex_cmp_empty(self, opname): + def test_ser_flex_cmp_return_dtypes_empty(self, opname): # GH#15115 empty Series case ser = Series([1, 3, 2], index=range(3)) empty = ser.iloc[:0] From b23d2e16075d0d3ecff44c08643846947b9e2b4e Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Tue, 30 Jan 2018 17:44:17 -0800 Subject: [PATCH 5/7] centralize Frame arith tests --- pandas/tests/frame/test_arithmetic.py | 47 +++++++++++++++++++++++++++ pandas/tests/frame/test_operators.py | 47 --------------------------- 2 files changed, 47 insertions(+), 47 deletions(-) diff --git a/pandas/tests/frame/test_arithmetic.py b/pandas/tests/frame/test_arithmetic.py index 37bfd8e100f3a..9b99a7b73b82b 100644 --- a/pandas/tests/frame/test_arithmetic.py +++ b/pandas/tests/frame/test_arithmetic.py @@ -62,6 +62,53 @@ def test_df_flex_cmp_constant_return_types_empty(self, opname): # ------------------------------------------------------------------- # Arithmetic +class TestFrameArithmetic(object): + + @pytest.mark.xfail(reason='GH#7996 datetime64 units not converted to nano') + def test_df_sub_datetime64_not_ns(self): + df = pd.DataFrame(pd.date_range('20130101', periods=3)) + dt64 = np.datetime64('2013-01-01') + assert dt64.dtype == 'datetime64[D]' + res = df - dt64 + expected = pd.DataFrame([pd.Timedelta(days=0), pd.Timedelta(days=1), + pd.Timedelta(days=2)]) + tm.assert_frame_equal(res, expected) + + @pytest.mark.parametrize('data', [ + [1, 2, 3], + [1.1, 2.2, 3.3], + [pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02'), pd.NaT], + ['x', 'y', 1]]) + @pytest.mark.parametrize('dtype', [None, object]) + def test_df_radd_str_invalid(self, dtype, data): + df = pd.DataFrame(data, dtype=dtype) + with pytest.raises(TypeError): + 'foo_' + df + + @pytest.mark.parametrize('dtype', [None, object]) + def test_df_with_dtype_radd_int(self, dtype): + df = pd.DataFrame([1, 2, 3], dtype=dtype) + expected = pd.DataFrame([2, 3, 4], dtype=dtype) + result = 1 + df + tm.assert_frame_equal(result, expected) + result = df + 1 + tm.assert_frame_equal(result, expected) + + @pytest.mark.parametrize('dtype', [None, object]) + def test_df_with_dtype_radd_nan(self, dtype): + df = pd.DataFrame([1, 2, 3], dtype=dtype) + expected = pd.DataFrame([np.nan, np.nan, np.nan], dtype=dtype) + result = np.nan + df + tm.assert_frame_equal(result, expected) + result = df + np.nan + tm.assert_frame_equal(result, expected) + + def test_df_radd_str(self): + df = pd.DataFrame(['x', np.nan, 'x']) + tm.assert_frame_equal('a' + df, pd.DataFrame(['ax', np.nan, 'ax'])) + tm.assert_frame_equal(df + 'a', pd.DataFrame(['xa', np.nan, 'xa'])) + + class TestPeriodFrameArithmetic(object): def test_ops_frame_period(self): diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index 84420184f776d..bdccbec6111d3 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -28,53 +28,6 @@ _check_mixed_int) -class TestDataFrameArithmetic(object): - - @pytest.mark.xfail(reason='GH#7996 datetime64 units not converted to nano') - def test_frame_sub_datetime64_not_ns(self): - df = pd.DataFrame(date_range('20130101', periods=3)) - dt64 = np.datetime64('2013-01-01') - assert dt64.dtype == 'datetime64[D]' - res = df - dt64 - expected = pd.DataFrame([pd.Timedelta(days=0), pd.Timedelta(days=1), - pd.Timedelta(days=2)]) - tm.assert_frame_equal(res, expected) - - @pytest.mark.parametrize('data', [ - [1, 2, 3], - [1.1, 2.2, 3.3], - [pd.Timestamp('2011-01-01'), pd.Timestamp('2011-01-02'), pd.NaT], - ['x', 'y', 1]]) - @pytest.mark.parametrize('dtype', [None, object]) - def test_frame_radd_str_invalid(self, dtype, data): - df = DataFrame(data, dtype=dtype) - with pytest.raises(TypeError): - 'foo_' + df - - @pytest.mark.parametrize('dtype', [None, object]) - def test_frame_with_dtype_radd_int(self, dtype): - df = pd.DataFrame([1, 2, 3], dtype=dtype) - expected = pd.DataFrame([2, 3, 4], dtype=dtype) - result = 1 + df - assert_frame_equal(result, expected) - result = df + 1 - assert_frame_equal(result, expected) - - @pytest.mark.parametrize('dtype', [None, object]) - def test_frame_with_dtype_radd_nan(self, dtype): - df = pd.DataFrame([1, 2, 3], dtype=dtype) - expected = pd.DataFrame([np.nan, np.nan, np.nan], dtype=dtype) - result = np.nan + df - assert_frame_equal(result, expected) - result = df + np.nan - assert_frame_equal(result, expected) - - def test_frame_radd_str(self): - df = pd.DataFrame(['x', np.nan, 'x']) - assert_frame_equal('a' + df, pd.DataFrame(['ax', np.nan, 'ax'])) - assert_frame_equal(df + 'a', pd.DataFrame(['xa', np.nan, 'xa'])) - - class TestDataFrameOperators(TestData): def test_operators(self): From c4d921def887e7f45f3c1fd2111801d767ff1e41 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Tue, 30 Jan 2018 17:49:27 -0800 Subject: [PATCH 6/7] fix misnamed test --- pandas/tests/series/test_arithmetic.py | 41 +++++++++++++------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index 05993afded30a..9381136a4235f 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -45,6 +45,18 @@ def test_ser_flex_cmp_return_dtypes_empty(self, opname): class TestTimestampSeriesComparison(object): + def test_dt64ser_cmp_period_scalar(self): + ser = Series(pd.period_range('2000-01-01', periods=10, freq='D')) + val = Period('2000-01-04', freq='D') + result = ser > val + expected = Series([x > val for x in ser]) + tm.assert_series_equal(result, expected) + + val = ser[5] + result = ser > val + expected = Series([x > val for x in ser]) + tm.assert_series_equal(result, expected) + def test_timestamp_compare_series(self): # make sure we can compare Timestamps on the right AND left hand side # GH#4982 @@ -108,20 +120,8 @@ def test_compare_timedelta_series(self): class TestPeriodSeriesComparisons(object): - def test_series_comparison_scalars(self): - ser = Series(pd.period_range('2000-01-01', periods=10, freq='D')) - val = Period('2000-01-04', freq='D') - result = ser > val - expected = Series([x > val for x in ser]) - tm.assert_series_equal(result, expected) - - val = ser[5] - result = ser > val - expected = Series([x > val for x in ser]) - tm.assert_series_equal(result, expected) - @pytest.mark.paramtrize('freq', ['M', '2M', '3M']) - def test_comp_series_period_scalar(self, freq): + def test_cmp_series_period_scalar(self, freq): # GH 13200 base = Series([Period(x, freq=freq) for x in ['2011-01', '2011-02', '2011-03', '2011-04']]) @@ -194,7 +194,7 @@ def test_cmp_series_period_series(self, freq): with tm.assert_raises_regex(IncompatibleFrequency, msg): base <= ser2 - def test_cmp_series_period_scalar(self): + def test_cmp_series_period_series_mixed_freq(self): # GH#13200 base = Series([Period('2011', freq='A'), Period('2011-02', freq='M'), @@ -224,6 +224,7 @@ def test_cmp_series_period_scalar(self): exp = Series([True, False, True, True]) tm.assert_series_equal(base <= ser, exp) + # ------------------------------------------------------------------ # Arithmetic @@ -260,10 +261,10 @@ def test_series_with_dtype_radd_nan(self, dtype): expected = pd.Series([np.nan, np.nan, np.nan], dtype=dtype) result = np.nan + ser - assert_series_equal(result, expected) + tm.assert_series_equal(result, expected) result = ser + np.nan - assert_series_equal(result, expected) + tm.assert_series_equal(result, expected) @pytest.mark.parametrize('dtype', [None, object]) def test_series_with_dtype_radd_int(self, dtype): @@ -271,15 +272,15 @@ def test_series_with_dtype_radd_int(self, dtype): expected = pd.Series([2, 3, 4], dtype=dtype) result = 1 + ser - assert_series_equal(result, expected) + tm.assert_series_equal(result, expected) result = ser + 1 - assert_series_equal(result, expected) + tm.assert_series_equal(result, expected) def test_series_radd_str(self): ser = pd.Series(['x', np.nan, 'x']) - assert_series_equal('a' + ser, pd.Series(['ax', np.nan, 'ax'])) - assert_series_equal(ser + 'a', pd.Series(['xa', np.nan, 'xa'])) + tm.assert_series_equal('a' + ser, pd.Series(['ax', np.nan, 'ax'])) + tm.assert_series_equal(ser + 'a', pd.Series(['xa', np.nan, 'xa'])) class TestPeriodSeriesArithmetic(object): From 76d32df98e118e2be4ab04cdddfff33e8068ce19 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Tue, 30 Jan 2018 18:44:45 -0800 Subject: [PATCH 7/7] typo fixup --- pandas/tests/series/test_arithmetic.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/tests/series/test_arithmetic.py b/pandas/tests/series/test_arithmetic.py index 9381136a4235f..1d9fa9dc15531 100644 --- a/pandas/tests/series/test_arithmetic.py +++ b/pandas/tests/series/test_arithmetic.py @@ -120,7 +120,7 @@ def test_compare_timedelta_series(self): class TestPeriodSeriesComparisons(object): - @pytest.mark.paramtrize('freq', ['M', '2M', '3M']) + @pytest.mark.parametrize('freq', ['M', '2M', '3M']) def test_cmp_series_period_scalar(self, freq): # GH 13200 base = Series([Period(x, freq=freq) for x in @@ -159,7 +159,7 @@ def test_cmp_series_period_scalar(self, freq): with tm.assert_raises_regex(IncompatibleFrequency, msg): Period('2011', freq='A') >= base - @pytest.mark.paramtrize('freq', ['M', '2M', '3M']) + @pytest.mark.parametrize('freq', ['M', '2M', '3M']) def test_cmp_series_period_series(self, freq): # GH#13200 base = Series([Period(x, freq=freq) for x in