Skip to content

Commit 5afd4b4

Browse files
committed
API: allow single element boolean Series to mimic numpy behavior( related GH4657)
TST: test for single element with null-like DOC: deprecation message for using bool(Series([True]))
1 parent ec77315 commit 5afd4b4

File tree

5 files changed

+36
-7
lines changed

5 files changed

+36
-7
lines changed

doc/source/release.rst

+2-1
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,8 @@ API Changes
241241

242242
- Infer and downcast dtype if ``downcast='infer'`` is passed to ``fillna/ffill/bfill`` (:issue:`4604`)
243243
- ``__nonzero__`` for all NDFrame objects, will now raise a ``ValueError``, this reverts back to (:issue:`1073`, :issue:`4633`)
244-
behavior.
244+
behavior (except for a single-element boolean Series, which mimics ``numpy`` behavior and will evaluate
245+
to the bool of the element)
245246
- ``DataFrame.update()`` no longer raises a ``DataConflictError``, it now
246247
will raise a ``ValueError`` instead (if necessary) (:issue:`4732`)
247248
- ``Series.isin()`` and ``DataFrame.isin()`` now raise a ``TypeError`` when

doc/source/v0.13.0.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,10 @@ API changes
5656

5757
- Infer and downcast dtype if ``downcast='infer'`` is passed to ``fillna/ffill/bfill`` (:issue:`4604`)
5858
- ``__nonzero__`` for all NDFrame objects, will now raise a ``ValueError``, this reverts back to (:issue:`1073`, :issue:`4633`)
59-
behavior. See :ref:`gotchas<gotchas.truth>` for a more detailed discussion.
59+
behavior (except for a single-element boolean Series, which mimics ``numpy`` behavior and will evaluate
60+
to the bool of the element). See :ref:`gotchas<gotchas.truth>` for a more detailed discussion.
6061

61-
This prevent behaviors like (which will now all raise ``ValueError``)
62+
This prevents behaviors like (which will now all raise ``ValueError``)
6263

6364
.. code-block:: python
6465

pandas/core/generic.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,8 @@ def empty(self):
596596
return not all(len(self._get_axis(a)) > 0 for a in self._AXIS_ORDERS)
597597

598598
def __nonzero__(self):
599-
raise ValueError("The truth value of an array is ambiguous. Use a.empty, a.item(), a.any() or a.all().")
599+
raise ValueError("The truth value of a {0} is ambiguous. "
600+
"Use a.empty, a.item(), a.any() or a.all().".format(self.__class__.__name__))
600601

601602
__bool__ = __nonzero__
602603

pandas/core/series.py

+12-1
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
import operator
99
import types
10+
import warnings
1011

1112
from numpy import nan, ndarray
1213
import numpy as np
@@ -364,6 +365,17 @@ def imag(self, v):
364365
__long__ = _coerce_method(int)
365366
__int__ = _coerce_method(int)
366367

368+
def __nonzero__(self):
369+
if len(self) == 1 and self.dtype == np.bool_:
370+
warnings.warn("bool on a single-element boolean dtyped Series is deprecated,\n"
371+
" please use a.empty, a.item(), a.any(), or a.all() instead\n",
372+
UserWarning)
373+
return bool(self.iloc[0])
374+
raise ValueError("The truth value of a {0} is ambiguous.\n"
375+
"Use a.empty, a.item(), a.any() or a.all().\n"
376+
"Currently, a boolean Series of length 1 is the exception\n".format(self.__class__.__name__))
377+
__bool__ = __nonzero__
378+
367379
# we are preserving name here
368380
def __getstate__(self):
369381
return dict(_data=self._data, name=self.name)
@@ -913,7 +925,6 @@ def to_string(self, buf=None, na_rep='NaN', float_format=None,
913925
"""
914926

915927
if nanRep is not None: # pragma: no cover
916-
import warnings
917928
warnings.warn("nanRep is deprecated, use na_rep", FutureWarning)
918929
na_rep = nanRep
919930

pandas/tests/test_generic.py

+17-2
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,26 @@ def test_get_numeric_data_preserve_dtype(self):
205205

206206
def test_nonzero_single_element(self):
207207

208+
# single item to follow numpy
208209
s = Series([True])
209-
self.assertRaises(ValueError, lambda : bool(s))
210+
self.assert_(bool(s) == True)
210211

211212
s = Series([False])
212-
self.assertRaises(ValueError, lambda : bool(s))
213+
self.assert_(bool(s) == False)
214+
215+
# single item nan to raise
216+
for s in [ Series([np.nan]), Series([pd.NaT]) ]:
217+
self.assertRaises(ValueError, lambda : bool(s))
218+
219+
# multiple bool are still an error
220+
for s in [Series([True,True]), Series([False, False])]:
221+
self.assertRaises(ValueError, lambda : bool(s))
222+
223+
# single non-bool are an error
224+
for s in [Series([1]), Series([0]),
225+
Series(['a']), Series([0.0])]:
226+
self.assertRaises(ValueError, lambda : bool(s))
227+
213228

214229
class TestDataFrame(unittest.TestCase, Generic):
215230
_typ = DataFrame

0 commit comments

Comments
 (0)