Skip to content

Commit 436f91c

Browse files
committed
BUG: isnull doesnt handle PeriodNaT properly
1 parent 391f46a commit 436f91c

File tree

4 files changed

+47
-5
lines changed

4 files changed

+47
-5
lines changed

pandas/core/common.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,8 @@ def _isnull_new(obj):
221221
return obj._constructor(obj._data.isnull(func=isnull))
222222
elif isinstance(obj, list) or hasattr(obj, '__array__'):
223223
return _isnull_ndarraylike(np.asarray(obj))
224+
elif isinstance(obj, pd.Period):
225+
return obj.ordinal == tslib.iNaT
224226
else:
225227
return obj is None
226228

@@ -291,7 +293,6 @@ def _isnull_ndarraylike(obj):
291293
values = values.values
292294
result = values.isnull()
293295
else:
294-
295296
# Working around NumPy ticket 1542
296297
shape = values.shape
297298

@@ -302,7 +303,7 @@ def _isnull_ndarraylike(obj):
302303
vec = lib.isnullobj(values.ravel())
303304
result[...] = vec.reshape(shape)
304305

305-
elif is_datetimelike(obj):
306+
elif dtype in _DATELIKE_DTYPES or isinstance(obj, pd.PeriodIndex):
306307
# this is the NaT pattern
307308
result = values.view('i8') == tslib.iNaT
308309
else:

pandas/lib.pyx

+5-1
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ cpdef checknull(object val):
218218
return get_timedelta64_value(val) == NPY_NAT
219219
elif is_array(val):
220220
return False
221+
# elif is_periodnat(val):
222+
# return True
221223
else:
222224
return _checknull(val)
223225

@@ -278,6 +280,8 @@ def item_from_zerodim(object val):
278280
"""
279281
return util.unbox_if_zerodim(val)
280282

283+
cdef is_periodnat(object val):
284+
return hasattr(val, 'freq') and getattr(val, 'ordinal', None) == iNaT
281285

282286
@cython.wraparound(False)
283287
@cython.boundscheck(False)
@@ -290,7 +294,7 @@ def isnullobj(ndarray[object] arr):
290294
result = np.zeros(n, dtype=np.uint8)
291295
for i from 0 <= i < n:
292296
val = arr[i]
293-
result[i] = val is NaT or _checknull(val)
297+
result[i] = val is NaT or _checknull(val) or is_periodnat(val)
294298
return result.view(np.bool_)
295299

296300
@cython.wraparound(False)

pandas/tests/test_common.py

+37
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import nose
88
from nose.tools import assert_equal
99
import numpy as np
10+
import pandas as pd
1011
from pandas.tslib import iNaT, NaT
1112
from pandas import Series, DataFrame, date_range, DatetimeIndex, Timestamp, Float64Index
1213
from pandas import compat
@@ -143,6 +144,18 @@ def test_isnull_nat():
143144
exp = np.array([True])
144145
assert(np.array_equal(result, exp))
145146

147+
result = isnull(pd.Period('NaT', freq='M'))
148+
assert(result)
149+
result = isnull([pd.Period('NaT', freq='M')])
150+
exp = np.array([True])
151+
assert(np.array_equal(result, exp))
152+
153+
result = notnull(pd.Period('NaT', freq='M'))
154+
assert(not result)
155+
result = notnull([pd.Period('NaT', freq='M')])
156+
exp = np.array([False])
157+
assert(np.array_equal(result, exp))
158+
146159
def test_isnull_datetime():
147160
assert (not isnull(datetime.now()))
148161
assert notnull(datetime.now())
@@ -166,6 +179,30 @@ def test_isnull_datetime():
166179
mask = isnull(pidx[1:])
167180
assert(not mask.any())
168181

182+
def test_isnull_period():
183+
assert (not isnull(pd.Period('2011-01', freq='M')))
184+
assert notnull(pd.Period('2011-01', freq='M'))
185+
186+
idx = pd.period_range('1/1/1990', periods=20)
187+
assert(notnull(idx).all())
188+
189+
idx = pd.PeriodIndex(['NaT', '2011-01', '2011-02'], freq='M')
190+
mask = isnull(idx)
191+
assert(mask[0])
192+
assert(not mask[1:].any())
193+
194+
mask = isnull(idx.asobject)
195+
assert(mask[0])
196+
assert(not mask[1:].any())
197+
198+
mask = notnull(idx)
199+
assert(not mask[0])
200+
assert(mask[1:].all())
201+
202+
mask = notnull(idx.asobject)
203+
assert(not mask[0])
204+
assert(mask[1:].all())
205+
169206

170207
class TestIsNull(tm.TestCase):
171208
def test_0d_array(self):

vb_suite/panel_methods.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
# shift
99

1010
setup = common_setup + """
11-
index = date_range(start="2000", freq="D", periods=1000)
12-
panel = Panel(np.random.randn(100, len(index), 1000))
11+
index = date_range(start="2000", freq="D", periods=100)
12+
panel = Panel(np.random.randn(100, len(index), 100))
1313
"""
1414

1515
panel_shift = Benchmark('panel.shift(1)', setup,

0 commit comments

Comments
 (0)