@@ -504,7 +504,7 @@ def take_1d(arr, indexer, out=None, fill_value=np.nan):
504504 dtype , fill_value = arr .dtype , arr .dtype .type ()
505505 else :
506506 indexer = _ensure_int64 (indexer )
507- dtype = _maybe_promote (arr .dtype , fill_value )
507+ dtype = _maybe_promote (arr .dtype , fill_value )[ 0 ]
508508 if dtype != arr .dtype :
509509 mask = indexer == - 1
510510 needs_masking = mask .any ()
@@ -552,7 +552,7 @@ def take_2d_multi(arr, row_idx, col_idx, fill_value=np.nan, out=None):
552552 else :
553553 col_idx = _ensure_int64 (col_idx )
554554
555- dtype = _maybe_promote (arr .dtype , fill_value )
555+ dtype = _maybe_promote (arr .dtype , fill_value )[ 0 ]
556556 if dtype != arr .dtype :
557557 row_mask = row_idx == - 1
558558 col_mask = col_idx == - 1
@@ -588,7 +588,7 @@ def diff(arr, n, axis=0):
588588 n = int (n )
589589 dtype = arr .dtype
590590 if issubclass (dtype .type , np .integer ):
591- dtype = np .float_
591+ dtype = np .float64
592592 elif issubclass (dtype .type , np .bool_ ):
593593 dtype = np .object_
594594
@@ -629,7 +629,7 @@ def take_fast(arr, indexer, mask, needs_masking, axis=0, out=None,
629629 else :
630630 indexer = _ensure_int64 (indexer )
631631 if needs_masking :
632- dtype = _maybe_promote (arr .dtype , fill_value )
632+ dtype = _maybe_promote (arr .dtype , fill_value )[ 0 ]
633633 if dtype != arr .dtype and out is not None and out .dtype != dtype :
634634 raise Exception ('Incompatible type for fill_value' )
635635 else :
@@ -644,16 +644,20 @@ def take_fast(arr, indexer, mask, needs_masking, axis=0, out=None,
644644 take_f (arr , indexer , out = out , fill_value = fill_value )
645645 return out
646646
647+
647648def _infer_dtype_from_scalar (val ):
648649 """ interpret the dtype from a scalar, upcast floats and ints
649650 return the new value and the dtype """
650651
652+ dtype = np .object_
653+
651654 # a 1-element ndarray
652655 if isinstance (val , pa .Array ):
653656 if val .ndim != 0 :
654657 raise ValueError ("invalid ndarray passed to _infer_dtype_from_scalar" )
655658
656- return val .item (), val .dtype
659+ dtype = val .dtype
660+ val = val .item ()
657661
658662 elif isinstance (val , basestring ):
659663
@@ -662,67 +666,79 @@ def _infer_dtype_from_scalar(val):
662666 # so this is kind of bad. Alternately we could use np.repeat
663667 # instead of np.empty (but then you still don't want things
664668 # coming out as np.str_!
665- return val , np .object_
669+
670+ dtype = np .object_
666671
667672 elif isinstance (val , np .datetime64 ):
668673 # ugly hacklet
669- val = lib .Timestamp (val ).value
670- return val , np .dtype ('M8[ns]' )
674+ val = lib .Timestamp (val ).value
675+ dtype = np .dtype ('M8[ns]' )
671676
672677 elif is_bool (val ):
673- return val , np .bool_
678+ dtype = np .bool_
674679
675680 # provide implicity upcast on scalars
676681 elif is_integer (val ):
677- return val , np .int64
682+ dtype = np .int64
683+
678684 elif is_float (val ):
679- return val , np .float64
685+ dtype = np .float64
680686
681687 elif is_complex (val ):
682- return val , np .complex_
688+ dtype = np .complex_
683689
684- return val , np . object_
690+ return dtype , val
685691
686692def _maybe_promote (dtype , fill_value = np .nan ):
693+ # returns tuple of (dtype, fill_value)
687694 if issubclass (dtype .type , np .datetime64 ):
688- # for now: refuse to upcast
695+ # for now: refuse to upcast datetime64
689696 # (this is because datetime64 will not implicitly upconvert
690697 # to object correctly as of numpy 1.6.1)
691- return dtype
698+ if isnull (fill_value ):
699+ fill_value = tslib .iNaT
700+ else :
701+ try :
702+ fill_value = lib .Timestamp (fill_value ).value
703+ except :
704+ # the proper thing to do here would probably be to upcast to
705+ # object (but numpy 1.6.1 doesn't do this properly)
706+ fill_value = tslib .iNaT
692707 elif is_float (fill_value ):
693708 if issubclass (dtype .type , np .bool_ ):
694- return np .object_
709+ dtype = np .object_
695710 elif issubclass (dtype .type , np .integer ):
696- return np .float64
697- return dtype
711+ dtype = np .float64
698712 elif is_bool (fill_value ):
699- if issubclass (dtype .type , np .bool_ ):
700- return dtype
701- return np .object_
713+ if not issubclass (dtype .type , np .bool_ ):
714+ dtype = np .object_
702715 elif is_integer (fill_value ):
703716 if issubclass (dtype .type , np .bool_ ):
704- return np .object_
717+ dtype = np .object_
705718 elif issubclass (dtype .type , np .integer ):
706719 # upcast to prevent overflow
707720 arr = np .asarray (fill_value )
708721 if arr != arr .astype (dtype ):
709- return arr .dtype
710- return dtype
711- return dtype
722+ dtype = arr .dtype
712723 elif is_complex (fill_value ):
713724 if issubclass (dtype .type , np .bool_ ):
714- return np .object_
725+ dtype = np .object_
715726 elif issubclass (dtype .type , (np .integer , np .floating )):
716- return np .complex_
717- return dtype
718- return np .object_
727+ dtype = np .complex128
728+ else :
729+ dtype = np .object_
730+ return dtype , fill_value
719731
720- def _maybe_upcast (values ):
721- """ provide explicty type promotion and coercion """
722- new_dtype = _maybe_promote (values .dtype )
732+ def _maybe_upcast (values , fill_value = np .nan , copy = False ):
733+ """ provide explicty type promotion and coercion
734+ if copy == True, then a copy is created even if no upcast is required """
735+
736+ new_dtype , fill_value = _maybe_promote (values .dtype , fill_value )
723737 if new_dtype != values .dtype :
724738 values = values .astype (new_dtype )
725- return values
739+ elif copy :
740+ values = values .copy ()
741+ return values , fill_value
726742
727743def _possibly_cast_item (obj , item , dtype ):
728744 chunk = obj [item ]
0 commit comments