Skip to content

Commit

Permalink
BUG:fixed inconsistent behavior of last_valid_index
Browse files Browse the repository at this point in the history
closes #12800
closes #12834
  • Loading branch information
gregorylivschitz authored and jreback committed Apr 11, 2016
1 parent e1aa2d9 commit b8ae20e
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 2 deletions.
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.18.1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ Bug Fixes


- Bug in ``.str`` accessor methods may raise ``ValueError`` if input has ``name`` and the result is ``DataFrame`` or ``MultiIndex`` (:issue:`12617`)

- Bug in ``DataFrame.last_valid_index()`` and ``DataFrame.first_valid_index()`` on empty frames (:issue:`12800`)


- Bug in ``CategoricalIndex.get_loc`` returns different result from regular ``Index`` (:issue:`12531`)
Expand Down
6 changes: 6 additions & 0 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -3766,12 +3766,18 @@ def first_valid_index(self):
"""
Return label for first non-NA/null value
"""
if len(self) == 0:
return None

return self.index[self.count(1) > 0][0]

def last_valid_index(self):
"""
Return label for last non-NA/null value
"""
if len(self) == 0:
return None

return self.index[self.count(1) > 0][-1]

# ----------------------------------------------------------------------
Expand Down
5 changes: 5 additions & 0 deletions pandas/tests/frame/test_timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,3 +336,8 @@ def test_first_last_valid(self):

index = frame.last_valid_index()
self.assertEqual(index, frame.index[-6])

# GH12800
empty = DataFrame()
self.assertIsNone(empty.last_valid_index())
self.assertIsNone(empty.first_valid_index())
11 changes: 10 additions & 1 deletion pandas/tests/series/test_timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@


class TestSeriesTimeSeries(TestData, tm.TestCase):

_multiprocess_can_split_ = True

def test_shift(self):
Expand Down Expand Up @@ -222,6 +221,7 @@ def test_asof(self):

def test_getitem_setitem_datetimeindex(self):
from pandas import date_range

N = 50
# testing with timezone, GH #2785
rng = date_range('1/1/1990', periods=N, freq='H', tz='US/Eastern')
Expand Down Expand Up @@ -304,6 +304,7 @@ def test_getitem_setitem_datetime_tz_pytz(self):
from pytz import timezone as tz

from pandas import date_range

N = 50
# testing with timezone, GH #2785
rng = date_range('1/1/1990', periods=N, freq='H', tz='US/Eastern')
Expand Down Expand Up @@ -343,6 +344,7 @@ def test_getitem_setitem_datetime_tz_dateutil(self):
x) # handle special case for utc in dateutil

from pandas import date_range

N = 50
# testing with timezone, GH #2785
rng = date_range('1/1/1990', periods=N, freq='H', tz='US/Eastern')
Expand Down Expand Up @@ -372,6 +374,7 @@ def test_getitem_setitem_datetime_tz_dateutil(self):

def test_getitem_setitem_periodindex(self):
from pandas import period_range

N = 50
rng = period_range('1/1/1990', periods=N, freq='H')
ts = Series(np.random.randn(N), index=rng)
Expand Down Expand Up @@ -460,6 +463,7 @@ def test_asof_periodindex(self):

def test_asof_more(self):
from pandas import date_range

s = Series([nan, nan, 1, 2, nan, nan, 3, 4, 5],
index=date_range('1/1/2000', periods=9))

Expand Down Expand Up @@ -605,6 +609,11 @@ def test_first_last_valid(self):
self.assertIsNone(ser.last_valid_index())
self.assertIsNone(ser.first_valid_index())

# GH12800
empty = Series()
self.assertIsNone(empty.last_valid_index())
self.assertIsNone(empty.first_valid_index())

def test_mpl_compat_hack(self):
result = self.ts[:, np.newaxis]
expected = self.ts.values[:, np.newaxis]
Expand Down

0 comments on commit b8ae20e

Please sign in to comment.