@@ -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,32 @@ 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
+ # A *while* loop test is extremely expensive for DataFrame
3762
+ # so we later pre-compute all the NAs and use the same
3763
+ # code path whether *where* is a scalar or list.
3764
+ # See PR: https://github.com/pandas-dev/pandas/pull/14476
3765
+ if is_series :
3766
+ loc = self .index .searchsorted (where , side = 'right' )
3767
+ if loc > 0 :
3768
+ loc -= 1
3769
+
3770
+ values = self ._values
3771
+ while loc > 0 and isnull (values [loc ]):
3772
+ loc -= 1
3773
+ return values [loc ]
3767
3774
3768
3775
if not isinstance (where , Index ):
3769
- where = Index (where )
3776
+ where = Index (where ) if is_list else Index ([ where ])
3770
3777
3778
+ nulls = self .isnull () if is_series else self [subset ].isnull ().any (1 )
3771
3779
locs = self .index .asof_locs (where , ~ (nulls .values ))
3772
3780
3773
3781
# mask the missing
3774
3782
missing = locs == - 1
3775
3783
data = self .take (locs , is_copy = False )
3776
3784
data .index = where
3777
3785
data .loc [missing ] = np .nan
3778
- return data
3786
+ return data if is_list else data . iloc [ - 1 ]
3779
3787
3780
3788
# ----------------------------------------------------------------------
3781
3789
# Action Methods
0 commit comments