Skip to content

Commit b4fd403

Browse files
Carlos Souzamattip
Carlos Souza
authored andcommitted
BUG: Series.asof fails for all NaN Series (GH15713)
closes bug pandas-dev#15713 Added the test if the series is all nans Added the code that check if that's the case: if yes, return the expected output Author: Carlos Souza <[email protected]> Closes pandas-dev#15758 from ucals/bug-fix-15713 and squashes the following commits: 0765108 [Carlos Souza] First simplification, code-block in the same place bb63964 [Carlos Souza] Propagating Series name af9a29b [Carlos Souza] Setting name of asof result when scalar input and all nan b8f078a [Carlos Souza] Small code standard change 7448b96 [Carlos Souza] Fixing scalar input a080b9b [Carlos Souza] Making scalar input return in a Series 04b7306 [Carlos Souza] Removing .values and formating code PEP8 3f9c7fd [Carlos Souza] Minor comments 70c958f [Carlos Souza] Added tests for non-default indexes, scalar and multiple inputs, and results preserve columns 6b745af [Carlos Souza] Adding DataFrame tests & support, and optimizing the code 89fb6cf [Carlos Souza] BUG pandas-dev#15713 fixing failing tests 17d1d77 [Carlos Souza] BUG pandas-dev#15713 Series.asof return nan when series is all nans! 4e26ab8 [Carlos Souza] BUG pandas-dev#15713 Series.asof return nan when series is all nans. c78d687 [Carlos Souza] BUG pandas-dev#15713 Series.asof return nan when series is all nans 676a4e5 [Carlos Souza] Test
1 parent 37eeecc commit b4fd403

File tree

4 files changed

+73
-11
lines changed

4 files changed

+73
-11
lines changed

doc/source/whatsnew/v0.20.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -868,6 +868,7 @@ Bug Fixes
868868
- Bug in ``pd.cut()`` with a single bin on an all 0s array (:issue:`15428`)
869869
- Bug in ``pd.qcut()`` with a single quantile and an array with identical values (:issue:`15431`)
870870
- Compat with SciPy 0.19.0 for testing on ``.interpolate()`` (:issue:`15662`)
871+
- Bug in ``Series.asof`` which raised if the series contained all ``np.nan`` (:issue:`15713`)
871872

872873
- Compat for 32-bit platforms for ``.qcut/cut``; bins will now be ``int64`` dtype (:issue:`14866`)
873874

pandas/core/generic.py

+10
Original file line numberDiff line numberDiff line change
@@ -3972,6 +3972,16 @@ def asof(self, where, subset=None):
39723972
where = Index(where) if is_list else Index([where])
39733973

39743974
nulls = self.isnull() if is_series else self[subset].isnull().any(1)
3975+
if nulls.all():
3976+
if is_series:
3977+
return self._constructor(np.nan, index=where, name=self.name)
3978+
elif is_list:
3979+
from pandas import DataFrame
3980+
return DataFrame(np.nan, index=where, columns=self.columns)
3981+
else:
3982+
from pandas import Series
3983+
return Series(np.nan, index=self.columns, name=where[0])
3984+
39753985
locs = self.index.asof_locs(where, ~(nulls.values))
39763986

39773987
# mask the missing

pandas/tests/frame/test_asof.py

+36-11
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,19 @@
44
from pandas import (DataFrame, date_range, Timestamp, Series,
55
to_datetime)
66

7-
from pandas.util.testing import assert_frame_equal, assert_series_equal
87
import pandas.util.testing as tm
98

109
from .common import TestData
1110

1211

1312
class TestFrameAsof(TestData, tm.TestCase):
14-
1513
def setUp(self):
1614
self.N = N = 50
17-
rng = date_range('1/1/1990', periods=N, freq='53s')
15+
self.rng = date_range('1/1/1990', periods=N, freq='53s')
1816
self.df = DataFrame({'A': np.arange(N), 'B': np.arange(N)},
19-
index=rng)
17+
index=self.rng)
2018

2119
def test_basic(self):
22-
2320
df = self.df.copy()
2421
df.loc[15:30, 'A'] = np.nan
2522
dates = date_range('1/1/1990', periods=self.N * 3,
@@ -39,7 +36,6 @@ def test_basic(self):
3936
self.assertTrue((rs == 14).all(1).all())
4037

4138
def test_subset(self):
42-
4339
N = 10
4440
rng = date_range('1/1/1990', periods=N, freq='53s')
4541
df = DataFrame({'A': np.arange(N), 'B': np.arange(N)},
@@ -51,19 +47,19 @@ def test_subset(self):
5147
# with a subset of A should be the same
5248
result = df.asof(dates, subset='A')
5349
expected = df.asof(dates)
54-
assert_frame_equal(result, expected)
50+
tm.assert_frame_equal(result, expected)
5551

5652
# same with A/B
5753
result = df.asof(dates, subset=['A', 'B'])
5854
expected = df.asof(dates)
59-
assert_frame_equal(result, expected)
55+
tm.assert_frame_equal(result, expected)
6056

6157
# B gives self.df.asof
6258
result = df.asof(dates, subset='B')
6359
expected = df.resample('25s', closed='right').ffill().reindex(dates)
6460
expected.iloc[20:] = 9
6561

66-
assert_frame_equal(result, expected)
62+
tm.assert_frame_equal(result, expected)
6763

6864
def test_missing(self):
6965
# GH 15118
@@ -75,9 +71,38 @@ def test_missing(self):
7571
result = df.asof('1989-12-31')
7672

7773
expected = Series(index=['A', 'B'], name=Timestamp('1989-12-31'))
78-
assert_series_equal(result, expected)
74+
tm.assert_series_equal(result, expected)
7975

8076
result = df.asof(to_datetime(['1989-12-31']))
8177
expected = DataFrame(index=to_datetime(['1989-12-31']),
8278
columns=['A', 'B'], dtype='float64')
83-
assert_frame_equal(result, expected)
79+
tm.assert_frame_equal(result, expected)
80+
81+
def test_all_nans(self):
82+
# GH 15713
83+
# DataFrame is all nans
84+
result = DataFrame([np.nan]).asof([0])
85+
expected = DataFrame([np.nan])
86+
tm.assert_frame_equal(result, expected)
87+
88+
# testing non-default indexes, multiple inputs
89+
dates = date_range('1/1/1990', periods=self.N * 3, freq='25s')
90+
result = DataFrame(np.nan, index=self.rng, columns=['A']).asof(dates)
91+
expected = DataFrame(np.nan, index=dates, columns=['A'])
92+
tm.assert_frame_equal(result, expected)
93+
94+
# testing multiple columns
95+
dates = date_range('1/1/1990', periods=self.N * 3, freq='25s')
96+
result = DataFrame(np.nan, index=self.rng,
97+
columns=['A', 'B', 'C']).asof(dates)
98+
expected = DataFrame(np.nan, index=dates, columns=['A', 'B', 'C'])
99+
tm.assert_frame_equal(result, expected)
100+
101+
# testing scalar input
102+
result = DataFrame(np.nan, index=[1, 2], columns=['A', 'B']).asof([3])
103+
expected = DataFrame(np.nan, index=[3], columns=['A', 'B'])
104+
tm.assert_frame_equal(result, expected)
105+
106+
result = DataFrame(np.nan, index=[1, 2], columns=['A', 'B']).asof(3)
107+
expected = Series(np.nan, index=['A', 'B'], name=3)
108+
tm.assert_series_equal(result, expected)

pandas/tests/series/test_asof.py

+26
Original file line numberDiff line numberDiff line change
@@ -148,3 +148,29 @@ def test_errors(self):
148148
s = Series(np.random.randn(N), index=rng)
149149
with self.assertRaises(ValueError):
150150
s.asof(s.index[0], subset='foo')
151+
152+
def test_all_nans(self):
153+
# GH 15713
154+
# series is all nans
155+
result = Series([np.nan]).asof([0])
156+
expected = Series([np.nan])
157+
tm.assert_series_equal(result, expected)
158+
159+
# testing non-default indexes
160+
N = 50
161+
rng = date_range('1/1/1990', periods=N, freq='53s')
162+
163+
dates = date_range('1/1/1990', periods=N * 3, freq='25s')
164+
result = Series(np.nan, index=rng).asof(dates)
165+
expected = Series(np.nan, index=dates)
166+
tm.assert_series_equal(result, expected)
167+
168+
# testing scalar input
169+
date = date_range('1/1/1990', periods=N * 3, freq='25s')[0]
170+
result = Series(np.nan, index=rng).asof(date)
171+
assert isnull(result)
172+
173+
# test name is propagated
174+
result = Series(np.nan, index=[1, 2, 3, 4], name='test').asof([4, 5])
175+
expected = Series(np.nan, index=[4, 5], name='test')
176+
tm.assert_series_equal(result, expected)

0 commit comments

Comments
 (0)