@@ -504,7 +504,7 @@ def take_1d(arr, indexer, out=None, fill_value=np.nan):
504
504
dtype , fill_value = arr .dtype , arr .dtype .type ()
505
505
else :
506
506
indexer = _ensure_int64 (indexer )
507
- dtype = _maybe_promote (arr .dtype , fill_value )
507
+ dtype = _maybe_promote (arr .dtype , fill_value )[ 0 ]
508
508
if dtype != arr .dtype :
509
509
mask = indexer == - 1
510
510
needs_masking = mask .any ()
@@ -552,7 +552,7 @@ def take_2d_multi(arr, row_idx, col_idx, fill_value=np.nan, out=None):
552
552
else :
553
553
col_idx = _ensure_int64 (col_idx )
554
554
555
- dtype = _maybe_promote (arr .dtype , fill_value )
555
+ dtype = _maybe_promote (arr .dtype , fill_value )[ 0 ]
556
556
if dtype != arr .dtype :
557
557
row_mask = row_idx == - 1
558
558
col_mask = col_idx == - 1
@@ -588,7 +588,7 @@ def diff(arr, n, axis=0):
588
588
n = int (n )
589
589
dtype = arr .dtype
590
590
if issubclass (dtype .type , np .integer ):
591
- dtype = np .float_
591
+ dtype = np .float64
592
592
elif issubclass (dtype .type , np .bool_ ):
593
593
dtype = np .object_
594
594
@@ -629,7 +629,7 @@ def take_fast(arr, indexer, mask, needs_masking, axis=0, out=None,
629
629
else :
630
630
indexer = _ensure_int64 (indexer )
631
631
if needs_masking :
632
- dtype = _maybe_promote (arr .dtype , fill_value )
632
+ dtype = _maybe_promote (arr .dtype , fill_value )[ 0 ]
633
633
if dtype != arr .dtype and out is not None and out .dtype != dtype :
634
634
raise Exception ('Incompatible type for fill_value' )
635
635
else :
@@ -644,16 +644,20 @@ def take_fast(arr, indexer, mask, needs_masking, axis=0, out=None,
644
644
take_f (arr , indexer , out = out , fill_value = fill_value )
645
645
return out
646
646
647
+
647
648
def _infer_dtype_from_scalar (val ):
648
649
""" interpret the dtype from a scalar, upcast floats and ints
649
650
return the new value and the dtype """
650
651
652
+ dtype = np .object_
653
+
651
654
# a 1-element ndarray
652
655
if isinstance (val , pa .Array ):
653
656
if val .ndim != 0 :
654
657
raise ValueError ("invalid ndarray passed to _infer_dtype_from_scalar" )
655
658
656
- return val .item (), val .dtype
659
+ dtype = val .dtype
660
+ val = val .item ()
657
661
658
662
elif isinstance (val , basestring ):
659
663
@@ -662,67 +666,79 @@ def _infer_dtype_from_scalar(val):
662
666
# so this is kind of bad. Alternately we could use np.repeat
663
667
# instead of np.empty (but then you still don't want things
664
668
# coming out as np.str_!
665
- return val , np .object_
669
+
670
+ dtype = np .object_
666
671
667
672
elif isinstance (val , np .datetime64 ):
668
673
# 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]' )
671
676
672
677
elif is_bool (val ):
673
- return val , np .bool_
678
+ dtype = np .bool_
674
679
675
680
# provide implicity upcast on scalars
676
681
elif is_integer (val ):
677
- return val , np .int64
682
+ dtype = np .int64
683
+
678
684
elif is_float (val ):
679
- return val , np .float64
685
+ dtype = np .float64
680
686
681
687
elif is_complex (val ):
682
- return val , np .complex_
688
+ dtype = np .complex_
683
689
684
- return val , np . object_
690
+ return dtype , val
685
691
686
692
def _maybe_promote (dtype , fill_value = np .nan ):
693
+ # returns tuple of (dtype, fill_value)
687
694
if issubclass (dtype .type , np .datetime64 ):
688
- # for now: refuse to upcast
695
+ # for now: refuse to upcast datetime64
689
696
# (this is because datetime64 will not implicitly upconvert
690
697
# 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
692
707
elif is_float (fill_value ):
693
708
if issubclass (dtype .type , np .bool_ ):
694
- return np .object_
709
+ dtype = np .object_
695
710
elif issubclass (dtype .type , np .integer ):
696
- return np .float64
697
- return dtype
711
+ dtype = np .float64
698
712
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_
702
715
elif is_integer (fill_value ):
703
716
if issubclass (dtype .type , np .bool_ ):
704
- return np .object_
717
+ dtype = np .object_
705
718
elif issubclass (dtype .type , np .integer ):
706
719
# upcast to prevent overflow
707
720
arr = np .asarray (fill_value )
708
721
if arr != arr .astype (dtype ):
709
- return arr .dtype
710
- return dtype
711
- return dtype
722
+ dtype = arr .dtype
712
723
elif is_complex (fill_value ):
713
724
if issubclass (dtype .type , np .bool_ ):
714
- return np .object_
725
+ dtype = np .object_
715
726
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
719
731
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 )
723
737
if new_dtype != values .dtype :
724
738
values = values .astype (new_dtype )
725
- return values
739
+ elif copy :
740
+ values = values .copy ()
741
+ return values , fill_value
726
742
727
743
def _possibly_cast_item (obj , item , dtype ):
728
744
chunk = obj [item ]
0 commit comments