66from pandas .core import common as com
77import pandas .core .nanops as nanops
88import pandas .tslib as tslib
9-
9+ from pandas . util . decorators import cache_readonly
1010
1111class StringMixin (object ):
1212
@@ -392,6 +392,11 @@ def _box_values(self, values):
392392 import pandas .lib as lib
393393 return lib .map_infer (values , self ._box_func )
394394
395+ @cache_readonly
396+ def hasnans (self ):
397+ """ return if I have any nans; enables various perf speedups """
398+ return (self .asi8 == tslib .iNaT ).any ()
399+
395400 @property
396401 def asobject (self ):
397402 from pandas .core .index import Index
@@ -408,11 +413,18 @@ def min(self, axis=None):
408413 Overridden ndarray.min to return an object
409414 """
410415 try :
411- mask = self .asi8 == tslib .iNaT
412- if mask .any ():
416+ i8 = self .asi8
417+
418+ # quick check
419+ if len (i8 ) and self .is_monotonic :
420+ if i8 [0 ] != tslib .iNaT :
421+ return self ._box_func (i8 [0 ])
422+
423+ if self .hasnans :
424+ mask = i8 == tslib .iNaT
413425 min_stamp = self [~ mask ].asi8 .min ()
414426 else :
415- min_stamp = self . asi8 .min ()
427+ min_stamp = i8 .min ()
416428 return self ._box_func (min_stamp )
417429 except ValueError :
418430 return self ._na_value
@@ -422,11 +434,18 @@ def max(self, axis=None):
422434 Overridden ndarray.max to return an object
423435 """
424436 try :
425- mask = self .asi8 == tslib .iNaT
426- if mask .any ():
437+ i8 = self .asi8
438+
439+ # quick check
440+ if len (i8 ) and self .is_monotonic :
441+ if i8 [- 1 ] != tslib .iNaT :
442+ return self ._box_func (i8 [- 1 ])
443+
444+ if self .hasnans :
445+ mask = i8 == tslib .iNaT
427446 max_stamp = self [~ mask ].asi8 .max ()
428447 else :
429- max_stamp = self . asi8 .max ()
448+ max_stamp = i8 .max ()
430449 return self ._box_func (max_stamp )
431450 except ValueError :
432451 return self ._na_value
0 commit comments