6
6
7
7
from pandas ._libs import lib , tslib , tslibs
8
8
from pandas ._libs .tslibs import NaT , OutOfBoundsDatetime , Period , iNaT
9
+ from pandas .util ._validators import validate_bool_kwarg
9
10
10
11
from .common import (
11
12
_INT64_DTYPE ,
@@ -696,9 +697,7 @@ def astype_nansafe(arr, dtype, copy=True, skipna=False):
696
697
elif np .issubdtype (arr .dtype , np .floating ) and np .issubdtype (dtype , np .integer ):
697
698
698
699
if not np .isfinite (arr ).all ():
699
- raise ValueError (
700
- "Cannot convert non-finite values (NA or inf) to " "integer"
701
- )
700
+ raise ValueError ("Cannot convert non-finite values (NA or inf) to integer" )
702
701
703
702
elif is_object_dtype (arr ):
704
703
@@ -719,9 +718,7 @@ def astype_nansafe(arr, dtype, copy=True, skipna=False):
719
718
return astype_nansafe (to_timedelta (arr ).values , dtype , copy = copy )
720
719
721
720
if dtype .name in ("datetime64" , "timedelta64" ):
722
- msg = (
723
- "The '{dtype}' dtype has no unit. " "Please pass in '{dtype}[ns]' instead."
724
- )
721
+ msg = "The '{dtype}' dtype has no unit. Please pass in '{dtype}[ns]' instead."
725
722
raise ValueError (msg .format (dtype = dtype .name ))
726
723
727
724
if copy or is_object_dtype (arr ) or is_object_dtype (dtype ):
@@ -731,50 +728,33 @@ def astype_nansafe(arr, dtype, copy=True, skipna=False):
731
728
return arr .view (dtype )
732
729
733
730
734
- def maybe_convert_objects (
735
- values , convert_dates = True , convert_numeric = True , convert_timedeltas = True , copy = True
736
- ):
737
- """ if we have an object dtype, try to coerce dates and/or numbers """
738
-
739
- # if we have passed in a list or scalar
740
- if isinstance (values , (list , tuple )):
741
- values = np .array (values , dtype = np .object_ )
742
- if not hasattr (values , "dtype" ):
743
- values = np .array ([values ], dtype = np .object_ )
731
+ def maybe_convert_objects (values : np .ndarray , convert_numeric : bool = True ):
732
+ """
733
+ If we have an object dtype array, try to coerce dates and/or numbers.
744
734
745
- # convert dates
746
- if convert_dates and values .dtype == np .object_ :
735
+ Parameters
736
+ ----------
737
+ values : ndarray
738
+ convert_numeric : bool, default True
747
739
748
- # we take an aggressive stance and convert to datetime64[ns]
749
- if convert_dates == "coerce" :
750
- new_values = maybe_cast_to_datetime (values , "M8[ns]" , errors = "coerce" )
740
+ Returns
741
+ -------
742
+ ndarray or DatetimeIndex
743
+ """
744
+ validate_bool_kwarg (convert_numeric , "convert_numeric" )
751
745
752
- # if we are all nans then leave me alone
753
- if not isna (new_values ).all ():
754
- values = new_values
746
+ orig_values = values
755
747
756
- else :
757
- values = lib .maybe_convert_objects (values , convert_datetime = convert_dates )
748
+ # convert dates
749
+ if is_object_dtype (values .dtype ):
750
+ values = lib .maybe_convert_objects (values , convert_datetime = True )
758
751
759
752
# convert timedeltas
760
- if convert_timedeltas and values .dtype == np .object_ :
761
-
762
- if convert_timedeltas == "coerce" :
763
- from pandas .core .tools .timedeltas import to_timedelta
764
-
765
- new_values = to_timedelta (values , errors = "coerce" )
766
-
767
- # if we are all nans then leave me alone
768
- if not isna (new_values ).all ():
769
- values = new_values
770
-
771
- else :
772
- values = lib .maybe_convert_objects (
773
- values , convert_timedelta = convert_timedeltas
774
- )
753
+ if is_object_dtype (values .dtype ):
754
+ values = lib .maybe_convert_objects (values , convert_timedelta = True )
775
755
776
756
# convert to numeric
777
- if values .dtype == np . object_ :
757
+ if is_object_dtype ( values .dtype ) :
778
758
if convert_numeric :
779
759
try :
780
760
new_values = lib .maybe_convert_numeric (
@@ -791,33 +771,38 @@ def maybe_convert_objects(
791
771
# soft-conversion
792
772
values = lib .maybe_convert_objects (values )
793
773
794
- values = values .copy () if copy else values
774
+ if values is orig_values :
775
+ values = values .copy ()
795
776
796
777
return values
797
778
798
779
799
780
def soft_convert_objects (
800
- values , datetime = True , numeric = True , timedelta = True , coerce = False , copy = True
781
+ values : np .ndarray ,
782
+ datetime : bool = True ,
783
+ numeric : bool = True ,
784
+ timedelta : bool = True ,
785
+ coerce : bool = False ,
786
+ copy : bool = True ,
801
787
):
802
788
""" if we have an object dtype, try to coerce dates and/or numbers """
803
789
790
+ validate_bool_kwarg (datetime , "datetime" )
791
+ validate_bool_kwarg (numeric , "numeric" )
792
+ validate_bool_kwarg (timedelta , "timedelta" )
793
+ validate_bool_kwarg (coerce , "coerce" )
794
+ validate_bool_kwarg (copy , "copy" )
795
+
804
796
conversion_count = sum ((datetime , numeric , timedelta ))
805
797
if conversion_count == 0 :
806
- raise ValueError (
807
- "At least one of datetime, numeric or timedelta must " "be True."
808
- )
798
+ raise ValueError ("At least one of datetime, numeric or timedelta must be True." )
809
799
elif conversion_count > 1 and coerce :
810
800
raise ValueError (
811
801
"Only one of 'datetime', 'numeric' or "
812
802
"'timedelta' can be True when when coerce=True."
813
803
)
814
804
815
- if isinstance (values , (list , tuple )):
816
- # List or scalar
817
- values = np .array (values , dtype = np .object_ )
818
- elif not hasattr (values , "dtype" ):
819
- values = np .array ([values ], dtype = np .object_ )
820
- elif not is_object_dtype (values .dtype ):
805
+ if not is_object_dtype (values .dtype ):
821
806
# If not object, do not attempt conversion
822
807
values = values .copy () if copy else values
823
808
return values
@@ -843,13 +828,13 @@ def soft_convert_objects(
843
828
# GH 20380, when datetime is beyond year 2262, hence outside
844
829
# bound of nanosecond-resolution 64-bit integers.
845
830
try :
846
- values = lib .maybe_convert_objects (values , convert_datetime = datetime )
831
+ values = lib .maybe_convert_objects (values , convert_datetime = True )
847
832
except OutOfBoundsDatetime :
848
833
pass
849
834
850
835
if timedelta and is_object_dtype (values .dtype ):
851
836
# Object check to ensure only run if previous did not convert
852
- values = lib .maybe_convert_objects (values , convert_timedelta = timedelta )
837
+ values = lib .maybe_convert_objects (values , convert_timedelta = True )
853
838
854
839
if numeric and is_object_dtype (values .dtype ):
855
840
try :
@@ -1368,7 +1353,7 @@ def maybe_cast_to_integer_array(arr, dtype, copy=False):
1368
1353
arr = np .asarray (arr )
1369
1354
1370
1355
if is_unsigned_integer_dtype (dtype ) and (arr < 0 ).any ():
1371
- raise OverflowError ("Trying to coerce negative values " " to unsigned integers" )
1356
+ raise OverflowError ("Trying to coerce negative values to unsigned integers" )
1372
1357
1373
1358
if is_integer_dtype (dtype ) and (is_float_dtype (arr ) or is_object_dtype (arr )):
1374
1359
raise ValueError ("Trying to coerce float values to integers" )
0 commit comments