Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 94fda23

Browse files
committedDec 14, 2012
TST: doc for inf_as_null. more testing to ensure inf not excluded by default. #2477
1 parent 6cadd6c commit 94fda23

File tree

5 files changed

+54
-15
lines changed

5 files changed

+54
-15
lines changed
 

‎doc/source/v0.10.0.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,20 @@ Note:
7575
# old behavior
7676
series.resample('D', how='sum', closed='right', label='right')
7777

78+
- Infinity and negative infinity are no longer treated as NA by ``isnull`` and
79+
``notnull``. That they every were was a relic of early pandas. This behavior
80+
can be re-enabled globally by the ``mode.use_inf_as_null`` option:
81+
82+
.. ipython:: python
83+
84+
s = pd.Series([1.5, np.inf, 3.4, -np.inf])
85+
pd.isnull(s)
86+
s.fillna(0)
87+
pd.set_option('use_inf_as_null', True)
88+
pd.isnull(s)
89+
s.fillna(0)
90+
pd.reset_option('use_inf_as_null')
91+
7892
- Methods with the ``inplace`` option now all return ``None`` instead of the
7993
calling object. E.g. code written like ``df = df.fillna(0, inplace=True)``
8094
may stop working. To fix, simply delete the unnecessary variable assignment.

‎pandas/core/common.py

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,7 @@ class AmbiguousIndexError(PandasError, KeyError):
4141

4242
def isnull(obj):
4343
'''
44-
Replacement for numpy.isnan / -numpy.isfinite which is suitable
45-
for use on object arrays.
44+
Detect missing values (NaN in numeric arrays, None/NaN in object arrays)
4645
4746
Parameters
4847
----------
@@ -52,6 +51,9 @@ def isnull(obj):
5251
-------
5352
boolean ndarray or boolean
5453
'''
54+
return _isnull(obj)
55+
56+
def _isnull_new(obj):
5557
if lib.isscalar(obj):
5658
return lib.checknull(obj)
5759

@@ -65,12 +67,10 @@ def isnull(obj):
6567
return _isnull_ndarraylike(obj)
6668
else:
6769
return obj is None
68-
isnull_new = isnull
6970

70-
def isnull_old(obj):
71+
def _isnull_old(obj):
7172
'''
72-
Replacement for numpy.isnan / -numpy.isfinite which is suitable
73-
for use on object arrays. Treat None, NaN, INF, -INF as null.
73+
Detect missing values. Treat None, NaN, INF, -INF as null.
7474
7575
Parameters
7676
----------
@@ -88,12 +88,14 @@ def isnull_old(obj):
8888
return _isnull_ndarraylike_old(obj)
8989
elif isinstance(obj, PandasObject):
9090
# TODO: optimize for DataFrame, etc.
91-
return obj.apply(isnull_old)
91+
return obj.apply(_isnull_old)
9292
elif isinstance(obj, list) or hasattr(obj, '__array__'):
9393
return _isnull_ndarraylike_old(obj)
9494
else:
9595
return obj is None
9696

97+
_isnull = _isnull_new
98+
9799
def _use_inf_as_null(key):
98100
'''Option change callback for null/inf behaviour
99101
Choose which replacement for numpy.isnan / -numpy.isfinite is used.
@@ -115,9 +117,9 @@ def _use_inf_as_null(key):
115117
'''
116118
flag = get_option(key)
117119
if flag == True:
118-
globals()['isnull'] = isnull_old
120+
globals()['_isnull'] = _isnull_old
119121
else:
120-
globals()['isnull'] = isnull_new
122+
globals()['_isnull'] = _isnull_new
121123

122124

123125

@@ -142,9 +144,11 @@ def _isnull_ndarraylike(obj):
142144
# this is the NaT pattern
143145
result = values.view('i8') == tslib.iNaT
144146
elif issubclass(values.dtype.type, np.timedelta64):
145-
result = -np.isfinite(values.view('i8'))
147+
# -np.isfinite(values.view('i8'))
148+
result = np.ones(values.shape, dtype=bool)
146149
else:
147-
result = -np.isfinite(obj)
150+
# -np.isfinite(obj)
151+
result = np.isnan(obj)
148152
return result
149153

150154

‎pandas/core/nanops.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from pandas.core.common import isnull, notnull
66
import pandas.core.common as com
7+
import pandas.core.config as cf
78
import pandas.lib as lib
89
import pandas.algos as algos
910
import pandas.hashtable as _hash

‎pandas/tests/test_common.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,18 @@ def test_notnull():
3434
assert notnull(np.inf)
3535
assert notnull(-np.inf)
3636

37+
arr = np.array([1.5, np.inf, 3.5, -np.inf])
38+
result = notnull(arr)
39+
assert result.all()
40+
3741
with cf.option_context("mode.use_inf_as_null",True):
3842
assert not notnull(np.inf)
3943
assert not notnull(-np.inf)
4044

45+
arr = np.array([1.5, np.inf, 3.5, -np.inf])
46+
result = notnull(arr)
47+
assert result.sum() == 2
48+
4149
with cf.option_context("mode.use_inf_as_null",False):
4250
float_series = Series(np.random.randn(5))
4351
obj_series = Series(np.random.randn(5), dtype=object)
@@ -63,6 +71,7 @@ def test_isnull():
6371
expected = result.apply(isnull)
6472
tm.assert_frame_equal(result, expected)
6573

74+
6675
def test_isnull_lists():
6776
result = isnull([[False]])
6877
exp = np.array([[False]])

‎pandas/tests/test_series.py

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
bdate_range, date_range)
1616
from pandas.core.index import MultiIndex
1717
from pandas.tseries.index import Timestamp, DatetimeIndex
18+
import pandas.core.config as cf
1819
import pandas.core.series as smod
1920
import pandas.lib as lib
2021

@@ -1200,18 +1201,28 @@ def test_sum(self):
12001201
self._check_stat_op('sum', np.sum)
12011202

12021203
def test_sum_inf(self):
1204+
import pandas.core.nanops as nanops
1205+
12031206
s = Series(np.random.randn(10))
12041207
s2 = s.copy()
1208+
12051209
s[5:8] = np.inf
12061210
s2[5:8] = np.nan
1207-
assert_almost_equal(s.sum(), s2.sum())
12081211

1209-
import pandas.core.nanops as nanops
1212+
self.assertTrue(np.isinf(s.sum()))
1213+
12101214
arr = np.random.randn(100, 100).astype('f4')
12111215
arr[:, 2] = np.inf
1216+
1217+
with cf.option_context("mode.use_inf_as_null", True):
1218+
assert_almost_equal(s.sum(), s2.sum())
1219+
1220+
res = nanops.nansum(arr, axis=1)
1221+
expected = nanops._nansum(arr, axis=1)
1222+
assert_almost_equal(res, expected)
1223+
12121224
res = nanops.nansum(arr, axis=1)
1213-
expected = nanops._nansum(arr, axis=1)
1214-
assert_almost_equal(res, expected)
1225+
self.assertTrue(np.isinf(res).all())
12151226

12161227
def test_mean(self):
12171228
self._check_stat_op('mean', np.mean)

0 commit comments

Comments
 (0)
Please sign in to comment.