Skip to content

Commit d665004

Browse files
committed
BUG: exclude NAs also with dtype=object in nanmean, others, GH #469
1 parent 34db250 commit d665004

File tree

4 files changed

+31
-31
lines changed

4 files changed

+31
-31
lines changed

RELEASE.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ Thanks
8585
- Jev Kuznetsov
8686
- Wouter Overmeire
8787
- Fernando Perez
88+
- Nathan Pinger
8889
- Christian Prinoth
8990
- Joon Ro
9091
- Chang She

pandas/core/nanops.py

Lines changed: 25 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,43 +10,36 @@
1010
_USE_BOTTLENECK = False
1111

1212
def nansum(values, axis=None, skipna=True, copy=True):
13-
if values.dtype == np.object_:
14-
the_sum = values.sum(axis)
15-
else:
16-
mask = isnull(values)
13+
mask = isnull(values)
1714

18-
if skipna and not issubclass(values.dtype.type, np.integer):
19-
if copy:
20-
values = values.copy()
21-
np.putmask(values, mask, 0)
15+
if skipna and not issubclass(values.dtype.type, np.integer):
16+
if copy:
17+
values = values.copy()
18+
np.putmask(values, mask, 0)
2219

23-
the_sum = values.sum(axis)
24-
the_sum = _maybe_null_out(the_sum, axis, mask)
20+
the_sum = values.sum(axis)
21+
the_sum = _maybe_null_out(the_sum, axis, mask)
2522

2623
return the_sum
2724

2825
def nanmean(values, axis=None, skipna=True, copy=True):
29-
if values.dtype == np.object_:
30-
the_mean = values.sum(axis) / float(values.shape[axis])
31-
else:
32-
mask = isnull(values)
33-
34-
if skipna and not issubclass(values.dtype.type, np.integer):
35-
if copy:
36-
values = values.copy()
37-
np.putmask(values, mask, 0)
26+
mask = isnull(values)
3827

39-
the_sum = values.sum(axis)
40-
count = _get_counts(mask, axis)
28+
if skipna and not issubclass(values.dtype.type, np.integer):
29+
if copy:
30+
values = values.copy()
31+
np.putmask(values, mask, 0)
4132

42-
if axis is not None:
43-
the_mean = the_sum / count
44-
ct_mask = count == 0
45-
if ct_mask.any():
46-
the_mean[ct_mask] = np.nan
47-
else:
48-
the_mean = the_sum / count if count > 0 else np.nan
33+
the_sum = values.sum(axis)
34+
count = _get_counts(mask, axis)
4935

36+
if axis is not None:
37+
the_mean = the_sum / count
38+
ct_mask = count == 0
39+
if ct_mask.any():
40+
the_mean[ct_mask] = np.nan
41+
else:
42+
the_mean = the_sum / count if count > 0 else np.nan
5043
return the_mean
5144

5245
def nanmedian(values, axis=None, skipna=True, copy=True):
@@ -121,7 +114,8 @@ def nanmin(values, axis=None, skipna=True, copy=True):
121114
# numpy 1.6.1 workaround in Python 3.x
122115
if values.dtype == np.object_: # pragma: no cover
123116
import __builtin__
124-
result = np.apply_along_axis(__builtin__.min, axis, values)
117+
apply_ax = axis if axis is not None else 0
118+
result = np.apply_along_axis(__builtin__.min, apply_ax, values)
125119
else:
126120
result = values.min(axis)
127121

@@ -136,7 +130,8 @@ def nanmax(values, axis=None, skipna=True, copy=True):
136130
# numpy 1.6.1 workaround in Python 3.x
137131
if values.dtype == np.object_: # pragma: no cover
138132
import __builtin__
139-
result = np.apply_along_axis(__builtin__.max, axis, values)
133+
apply_ax = axis if axis is not None else 0
134+
result = np.apply_along_axis(__builtin__.max, apply_ax, values)
140135
else:
141136
result = values.max(axis)
142137
return _maybe_null_out(result, axis, mask)

pandas/tests/test_frame.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3234,7 +3234,7 @@ def test_count(self):
32343234
def test_sum(self):
32353235
self._check_stat_op('sum', np.sum, has_numeric_only=True)
32363236

3237-
def test_stat_ops_attempt_obj_array(self):
3237+
def test_stat_operators_attempt_obj_array(self):
32383238
data = {
32393239
'a': [-0.00049987540199591344, -0.0016467257772919831,
32403240
0.00067695870775883013],

pandas/tests/test_series.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,10 @@ def _check_stat_op(self, name, alternate):
603603
allna = self.series * nan
604604
self.assert_(np.isnan(f(allna)))
605605

606+
# dtype=object with None, it works!
607+
s = Series([1, 2, 3, None, 5])
608+
f(s)
609+
606610
def _check_accum_op(self, name):
607611
func = getattr(np, name)
608612
self.assert_(np.array_equal(func(self.ts), func(np.array(self.ts))))

0 commit comments

Comments
 (0)