@@ -219,7 +219,7 @@ def f(self, *args, **kwargs):
219
219
return f
220
220
221
221
_stat_doc = """
222
- Return %(name)s of values
222
+ Return %(name)s of values
223
223
%(na_action)s
224
224
225
225
Parameters
@@ -238,7 +238,21 @@ def f(self, *args, **kwargs):
238
238
_doc_ndarray_interface = ("Extra parameters are to preserve ndarray"
239
239
"interface.\n " )
240
240
241
- #-------------------------------------------------------------------------------
241
+
242
+ def _make_stat_func (nanop , name , shortname , na_action = _doc_exclude_na ,
243
+ extras = _doc_ndarray_interface ):
244
+
245
+ @Substitution (name = name , shortname = shortname ,
246
+ na_action = na_action , extras = extras )
247
+ @Appender (_stat_doc )
248
+ def f (self , axis = 0 , dtype = None , out = None , skipna = True , level = None ):
249
+ if level is not None :
250
+ return self ._agg_by_level (shortname , level = level , skipna = skipna )
251
+ return nanop (self .values , skipna = skipna )
252
+ f .__name__ = shortname
253
+ return f
254
+
255
+ #----------------------------------------------------------------------
242
256
# Series class
243
257
244
258
class Series (np .ndarray , generic .PandasObject ):
@@ -985,21 +999,10 @@ def nunique(self):
985
999
"""
986
1000
return len (self .value_counts ())
987
1001
988
- @Substitution (name = 'sum' , shortname = 'sum' , na_action = _doc_exclude_na ,
989
- extras = _doc_ndarray_interface )
990
- @Appender (_stat_doc )
991
- def sum (self , axis = 0 , dtype = None , out = None , skipna = True , level = None ):
992
- if level is not None :
993
- return self ._agg_by_level ('sum' , level = level , skipna = skipna )
994
- return nanops .nansum (self .values , skipna = skipna )
995
-
996
- @Substitution (name = 'mean' , shortname = 'mean' , na_action = _doc_exclude_na ,
997
- extras = _doc_ndarray_interface )
998
- @Appender (_stat_doc )
999
- def mean (self , axis = 0 , dtype = None , out = None , skipna = True , level = None ):
1000
- if level is not None :
1001
- return self ._agg_by_level ('mean' , level = level , skipna = skipna )
1002
- return nanops .nanmean (self .values , skipna = skipna )
1002
+ sum = _make_stat_func (nanops .nansum , 'sum' , 'sum' )
1003
+ mean = _make_stat_func (nanops .nanmean , 'mean' , 'mean' )
1004
+ median = _make_stat_func (nanops .nanmedian , 'median' , 'median' , extras = '' )
1005
+ prod = _make_stat_func (nanops .nanprod , 'product' , 'prod' , extras = '' )
1003
1006
1004
1007
@Substitution (name = 'mean absolute deviation' , shortname = 'mad' ,
1005
1008
na_action = _doc_exclude_na , extras = '' )
@@ -1011,22 +1014,6 @@ def mad(self, skipna=True, level=None):
1011
1014
demeaned = self - self .mean (skipna = skipna )
1012
1015
return np .abs (demeaned ).mean (skipna = skipna )
1013
1016
1014
- @Substitution (name = 'median' , shortname = 'median' ,
1015
- na_action = _doc_exclude_na , extras = '' )
1016
- @Appender (_stat_doc )
1017
- def median (self , skipna = True , level = None ):
1018
- if level is not None :
1019
- return self ._agg_by_level ('median' , level = level , skipna = skipna )
1020
- return nanops .nanmedian (self .values , skipna = skipna )
1021
-
1022
- @Substitution (name = 'product' , shortname = 'product' ,
1023
- na_action = _doc_exclude_na , extras = '' )
1024
- @Appender (_stat_doc )
1025
- def prod (self , axis = None , dtype = None , out = None , skipna = True , level = None ):
1026
- if level is not None :
1027
- return self ._agg_by_level ('prod' , level = level , skipna = skipna )
1028
- return nanops .nanprod (self .values , skipna = skipna )
1029
-
1030
1017
@Substitution (name = 'minimum' , shortname = 'min' ,
1031
1018
na_action = _doc_exclude_na , extras = '' )
1032
1019
@Appender (_stat_doc )
@@ -2278,7 +2265,7 @@ def shift(self, periods=1, freq=None, **kwds):
2278
2265
return Series (self , index = self .index .shift (periods , offset ),
2279
2266
name = self .name )
2280
2267
2281
- def asof (self , date ):
2268
+ def asof (self , where ):
2282
2269
"""
2283
2270
Return last good (non-NaN) value in TimeSeries if value is NaN for
2284
2271
requested date.
@@ -2287,7 +2274,7 @@ def asof(self, date):
2287
2274
2288
2275
Parameters
2289
2276
----------
2290
- date : datetime or similar value
2277
+ wehre : date or array of dates
2291
2278
2292
2279
Notes
2293
2280
-----
@@ -2297,46 +2284,27 @@ def asof(self, date):
2297
2284
-------
2298
2285
value or NaN
2299
2286
"""
2300
- if isinstance (date , basestring ):
2301
- date = datetools .to_datetime (date )
2302
-
2303
- if not isinstance (date , (list , tuple , np .ndarray , Index )):
2304
- # treat scalar values differently
2305
- v = self .get (date )
2306
- if isnull (v ):
2307
- candidates = self .index [notnull (self )]
2308
- index = candidates .searchsorted (lib .Timestamp (date ))
2309
- if index > 0 :
2310
- asOfDate = candidates [index - 1 ]
2311
- return self .get (asOfDate )
2312
- return nan
2313
- return v
2287
+ if isinstance (where , basestring ):
2288
+ where = datetools .to_datetime (where )
2314
2289
2315
- if not isinstance (date , Index ):
2316
- date = Index (date )
2317
-
2318
- candidates = self .index [notnull (self )]
2319
-
2320
- mask = date .isin (candidates )
2321
-
2322
- there = self [date [mask ]]
2323
- todo = date [- mask ]
2324
-
2325
- if len (there ) == len (date ):
2326
- if len (there ) == 1 :
2327
- return there [0 ]
2328
- return there
2329
-
2330
- index = candidates .searchsorted (todo )
2331
- index = index - 1
2332
- asof_mask = index >= 0
2333
- asof = self .ix [candidates [index [asof_mask ]]]
2334
- asof .index = todo [asof_mask ]
2335
-
2336
- if len (date ) == 1 and len (asof ) > 0 :
2337
- return asof [0 ]
2290
+ values = self .values
2338
2291
2339
- return there .combine_first (asof ).reindex (date )
2292
+ if not hasattr (where , '__iter__' ):
2293
+ if where < self .index [0 ]:
2294
+ return np .nan
2295
+ loc = self .index .searchsorted (where , side = 'right' )
2296
+ if loc > 0 :
2297
+ loc -= 1
2298
+ while isnull (values [loc ]) and loc > 0 :
2299
+ loc -= 1
2300
+ return values [loc ]
2301
+
2302
+ if not isinstance (where , Index ):
2303
+ where = Index (where )
2304
+
2305
+ locs = self .index .asof_locs (where , notnull (values ))
2306
+ new_values = com .take_1d (values , locs )
2307
+ return Series (new_values , index = where , name = self .name )
2340
2308
2341
2309
def interpolate (self , method = 'linear' ):
2342
2310
"""
0 commit comments