diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index dacd433f112a5..11507b5d3cb43 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -308,8 +308,9 @@ Numeric - Bug in :meth:`Series.divmod` and :meth:`Series.rdivmod` which would raise an (incorrect) ``ValueError`` rather than return a pair of :class:`Series` objects as result (:issue:`25557`) - Raises a helpful exception when a non-numeric index is sent to :meth:`interpolate` with methods which require numeric index. (:issue:`21662`) - Bug in :meth:`~pandas.eval` when comparing floats with scalar operators, for example: ``x < -0.1`` (:issue:`25928`) +- Fixed bug where casting all-boolean array to integer extension array failed (:issue:`25211`) +- - - Conversion ^^^^^^^^^^ diff --git a/pandas/core/arrays/integer.py b/pandas/core/arrays/integer.py index 8e81066de71cb..42aa6a055acca 100644 --- a/pandas/core/arrays/integer.py +++ b/pandas/core/arrays/integer.py @@ -188,6 +188,9 @@ def coerce_to_array(values, dtype, mask=None, copy=False): raise TypeError("{} cannot be converted to an IntegerDtype".format( values.dtype)) + elif is_bool_dtype(values) and is_integer_dtype(dtype): + values = np.array(values, dtype=int, copy=copy) + elif not (is_integer_dtype(values) or is_float_dtype(values)): raise TypeError("{} cannot be converted to an IntegerDtype".format( values.dtype)) diff --git a/pandas/core/series.py b/pandas/core/series.py index e23d0bf6a5b83..f0b674596656a 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -2670,7 +2670,6 @@ def combine(self, other, func, fill_value=None): # do in _values_from_sequence. We still want ops to work # though, so we catch any regular Exception. pass - return self._constructor(new_values, index=new_index, name=new_name) def combine_first(self, other): diff --git a/pandas/tests/arrays/test_integer.py b/pandas/tests/arrays/test_integer.py index 759dacd7f221e..066eadc9b68bc 100644 --- a/pandas/tests/arrays/test_integer.py +++ b/pandas/tests/arrays/test_integer.py @@ -613,6 +613,19 @@ def test_to_integer_array_float(): assert result.dtype == Int64Dtype() +@pytest.mark.parametrize( + 'bool_values, int_values, target_dtype, expected_dtype', + [([False, True], [0, 1], Int64Dtype(), Int64Dtype()), + ([False, True], [0, 1], 'Int64', Int64Dtype()), + ([False, True, np.nan], [0, 1, np.nan], Int64Dtype(), Int64Dtype())]) +def test_to_integer_array_bool(bool_values, int_values, target_dtype, + expected_dtype): + result = integer_array(bool_values, dtype=target_dtype) + assert result.dtype == expected_dtype + expected = integer_array(int_values, dtype=target_dtype) + tm.assert_extension_array_equal(result, expected) + + @pytest.mark.parametrize( 'values, to_dtype, result_dtype', [