Skip to content

Commit 3841ae6

Browse files
committed
Merge pull request #4440 from cpcloud/fix-cumsum-bool
BUG: allow cumprod and cumsum to work with bool dtypes
2 parents c51a0db + 9da899b commit 3841ae6

File tree

3 files changed

+39
-2
lines changed

3 files changed

+39
-2
lines changed

doc/source/release.rst

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,8 @@ pandas 0.13
127127
(:issue:`3440`)
128128
- Fixed an issue where duplicate indexes were raising when plotting
129129
(:issue:`4486`)
130+
- Fixed an issue where cumsum and cumprod didn't work with bool dtypes
131+
(:issue:`4170`, :issue:`4440`)
130132

131133
pandas 0.12
132134
===========

pandas/core/series.py

+4-2
Original file line numberDiff line numberDiff line change
@@ -1654,7 +1654,8 @@ def cumsum(self, axis=0, dtype=None, out=None, skipna=True):
16541654
"""
16551655
arr = self.values.copy()
16561656

1657-
do_mask = skipna and not issubclass(self.dtype.type, np.integer)
1657+
do_mask = skipna and not issubclass(self.dtype.type,
1658+
(np.integer, np.bool_))
16581659
if do_mask:
16591660
mask = isnull(arr)
16601661
np.putmask(arr, mask, 0.)
@@ -1683,7 +1684,8 @@ def cumprod(self, axis=0, dtype=None, out=None, skipna=True):
16831684
"""
16841685
arr = self.values.copy()
16851686

1686-
do_mask = skipna and not issubclass(self.dtype.type, np.integer)
1687+
do_mask = skipna and not issubclass(self.dtype.type,
1688+
(np.integer, np.bool_))
16871689
if do_mask:
16881690
mask = isnull(arr)
16891691
np.putmask(arr, mask, 1.)

pandas/tests/test_series.py

+33
Original file line numberDiff line numberDiff line change
@@ -3963,6 +3963,39 @@ def test_bfill(self):
39633963
ts[2] = np.NaN
39643964
assert_series_equal(ts.bfill(), ts.fillna(method='bfill'))
39653965

3966+
def test_cummethods_bool(self):
3967+
def cummin(x):
3968+
return np.minimum.accumulate(x)
3969+
3970+
def cummax(x):
3971+
return np.maximum.accumulate(x)
3972+
3973+
from itertools import product
3974+
a = pd.Series([False, False, False, True, True, False, False])
3975+
b = ~a
3976+
c = pd.Series([False] * len(b))
3977+
d = ~c
3978+
methods = {'cumsum': np.cumsum, 'cumprod': np.cumprod,
3979+
'cummin': cummin, 'cummax': cummax}
3980+
args = product((a, b, c, d), methods)
3981+
for s, method in args:
3982+
expected = Series(methods[method](s.values))
3983+
result = getattr(s, method)()
3984+
assert_series_equal(result, expected)
3985+
3986+
e = pd.Series([False, True, nan, False])
3987+
cse = pd.Series([0, 1, nan, 1], dtype=object)
3988+
cpe = pd.Series([False, 0, nan, 0])
3989+
cmin = pd.Series([False, False, nan, False])
3990+
cmax = pd.Series([False, True, nan, True])
3991+
expecteds = {'cumsum': cse, 'cumprod': cpe, 'cummin': cmin,
3992+
'cummax': cmax}
3993+
3994+
for method in methods:
3995+
res = getattr(e, method)()
3996+
assert_series_equal(res, expecteds[method])
3997+
3998+
39663999
def test_replace(self):
39674000
N = 100
39684001
ser = Series(np.random.randn(N))

0 commit comments

Comments
 (0)