diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index 798151971363e..8c7e3acc97305 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -437,9 +437,10 @@ Bug Fixes - Bug in ``Series`` constructor when both ``copy=True`` and ``dtype`` arguments are provided (:issue:`15125`) - Bug in ``pd.read_csv()`` for the C engine where ``usecols`` were being indexed incorrectly with ``parse_dates`` (:issue:`14792`) - +- Incorrect dtyped ``Series`` was returned by comparison methods (e.g., ``lt``, ``gt``, ...) against a constant for an empty ``DataFrame`` (:issue:`15077`) - Bug in ``Series.dt.round`` inconsistent behaviour on NAT's with different arguments (:issue:`14940`) + - Bug in ``.read_json()`` for Python 2 where ``lines=True`` and contents contain non-ascii unicode characters (:issue:`15132`) - Bug in ``pd.read_csv()`` with ``float_precision='round_trip'`` which caused a segfault when a text entry is parsed (:issue:`15140`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index ef8b7a0d16bdc..799e2f266a137 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3595,9 +3595,6 @@ def _combine_match_columns(self, other, func, level=None, fill_value=None): return self._constructor(new_data) def _combine_const(self, other, func, raise_on_error=True): - if self.empty: - return self - new_data = self._data.eval(func=func, other=other, raise_on_error=raise_on_error) return self._constructor(new_data) diff --git a/pandas/tests/frame/test_operators.py b/pandas/tests/frame/test_operators.py index ef6297fc0b52e..f843a5c08ce05 100644 --- a/pandas/tests/frame/test_operators.py +++ b/pandas/tests/frame/test_operators.py @@ -671,6 +671,22 @@ 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() + self.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() + self.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') diff --git a/pandas/tests/series/test_operators.py b/pandas/tests/series/test_operators.py index 6650a171b818b..b013e1a6f1c10 100644 --- a/pandas/tests/series/test_operators.py +++ b/pandas/tests/series/test_operators.py @@ -1294,6 +1294,20 @@ def test_comparison_flex_alignment_fill(self): exp = pd.Series([True, True, False, False], index=list('abcd')) assert_series_equal(left.gt(right, fill_value=0), exp) + 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() + self.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() + self.assert_series_equal(result, Series([1], ['bool'])) + def test_operators_bitwise(self): # GH 9016: support bitwise op for integer types index = list('bca')