@@ -3735,10 +3735,10 @@ def asof(self, where, subset=None):
3735
3735
if not self .index .is_monotonic :
3736
3736
raise ValueError ("asof requires a sorted index" )
3737
3737
3738
- if isinstance (self , ABCSeries ):
3738
+ is_series = isinstance (self , ABCSeries )
3739
+ if is_series :
3739
3740
if subset is not None :
3740
3741
raise ValueError ("subset is not valid for Series" )
3741
- nulls = self .isnull ()
3742
3742
elif self .ndim > 2 :
3743
3743
raise NotImplementedError ("asof is not implemented "
3744
3744
"for {type}" .format (type (self )))
@@ -3747,9 +3747,9 @@ def asof(self, where, subset=None):
3747
3747
subset = self .columns
3748
3748
if not is_list_like (subset ):
3749
3749
subset = [subset ]
3750
- nulls = self [subset ].isnull ().any (1 )
3751
3750
3752
- if not is_list_like (where ):
3751
+ is_list = is_list_like (where )
3752
+ if not is_list :
3753
3753
start = self .index [0 ]
3754
3754
if isinstance (self .index , PeriodIndex ):
3755
3755
where = Period (where , freq = self .index .freq ).ordinal
@@ -3758,24 +3758,34 @@ def asof(self, where, subset=None):
3758
3758
if where < start :
3759
3759
return np .nan
3760
3760
3761
- loc = self .index .searchsorted (where , side = 'right' )
3762
- if loc > 0 :
3763
- loc -= 1
3764
- while nulls [loc ] and loc > 0 :
3765
- loc -= 1
3766
- return self .iloc [loc ]
3761
+ # It's always much faster to use a *while* loop here for
3762
+ # Series than pre-computing all the NAs. However a
3763
+ # *while* loop is extremely expensive for DataFrame
3764
+ # so we later pre-compute all the NAs and use the same
3765
+ # code path whether *where* is a scalar or list.
3766
+ # See PR: https://github.com/pandas-dev/pandas/pull/14476
3767
+ if is_series :
3768
+ loc = self .index .searchsorted (where , side = 'right' )
3769
+ if loc > 0 :
3770
+ loc -= 1
3771
+
3772
+ values = self ._values
3773
+ while loc > 0 and isnull (values [loc ]):
3774
+ loc -= 1
3775
+ return values [loc ]
3767
3776
3768
3777
if not isinstance (where , Index ):
3769
- where = Index (where )
3778
+ where = Index (where ) if is_list else Index ([ where ])
3770
3779
3780
+ nulls = self .isnull () if is_series else self [subset ].isnull ().any (1 )
3771
3781
locs = self .index .asof_locs (where , ~ (nulls .values ))
3772
3782
3773
3783
# mask the missing
3774
3784
missing = locs == - 1
3775
3785
data = self .take (locs , is_copy = False )
3776
3786
data .index = where
3777
3787
data .loc [missing ] = np .nan
3778
- return data
3788
+ return data if is_list else data . iloc [ - 1 ]
3779
3789
3780
3790
# ----------------------------------------------------------------------
3781
3791
# Action Methods
0 commit comments