@@ -96,7 +96,7 @@ cdef class Seen(object):
96
96
encountered when trying to perform type conversions.
97
97
"""
98
98
99
- cdef public :
99
+ cdef:
100
100
bint int_ # seen_int
101
101
bint bool_ # seen_bool
102
102
bint null_ # seen_null
@@ -185,7 +185,7 @@ cdef class Seen(object):
185
185
self .null_ = 1
186
186
self .float_ = 1
187
187
188
- def saw_int (self , val ):
188
+ cdef saw_int(self , object val):
189
189
"""
190
190
Set flags indicating that an integer value was encountered.
191
191
@@ -196,7 +196,7 @@ cdef class Seen(object):
196
196
"""
197
197
self .int_ = 1
198
198
self .sint_ = self .sint_ or (val < 0 )
199
- self .uint_ = self .uint_ or (val > iINT64_MAX )
199
+ self .uint_ = self .uint_ or (val > oINT64_MAX )
200
200
201
201
@property
202
202
def numeric_ (self ):
@@ -908,11 +908,15 @@ cpdef bint is_interval_array(ndarray[object] values):
908
908
cdef extern from " parse_helper.h" :
909
909
inline int floatify(object , double * result, int * maybe_int) except - 1
910
910
911
- cdef int64_t iINT64_MAX = < int64_t> INT64_MAX
912
- cdef int64_t iINT64_MIN = < int64_t> INT64_MIN
913
- cdef uint64_t iUINT64_MAX = < uint64_t> UINT64_MAX
911
+ # constants that will be compared to potentially arbitrarily large
912
+ # python int
913
+ cdef object oINT64_MAX = < int64_t> INT64_MAX
914
+ cdef object oINT64_MIN = < int64_t> INT64_MIN
915
+ cdef object oUINT64_MAX = < uint64_t> UINT64_MAX
914
916
915
917
918
+ @ cython.boundscheck (False )
919
+ @ cython.wraparound (False )
916
920
def maybe_convert_numeric (ndarray[object] values , set na_values ,
917
921
bint convert_empty = True , bint coerce_numeric = False ):
918
922
"""
@@ -943,6 +947,17 @@ def maybe_convert_numeric(ndarray[object] values, set na_values,
943
947
-------
944
948
numeric_array : array of converted object values to numerical ones
945
949
"""
950
+ # fastpath for ints - try to convert all based on first value
951
+ cdef object val = values[0 ]
952
+ if util.is_integer_object(val):
953
+ try :
954
+ maybe_ints = values.astype(' i8' )
955
+ if (maybe_ints == values).all():
956
+ return maybe_ints
957
+ except (ValueError , OverflowError , TypeError ):
958
+ pass
959
+
960
+ # otherwise, iterate and do full infererence
946
961
cdef:
947
962
int status, maybe_int
948
963
Py_ssize_t i, n = values.size
@@ -952,7 +967,6 @@ def maybe_convert_numeric(ndarray[object] values, set na_values,
952
967
ndarray[int64_t] ints = np.empty(n, dtype = ' i8' )
953
968
ndarray[uint64_t] uints = np.empty(n, dtype = ' u8' )
954
969
ndarray[uint8_t] bools = np.empty(n, dtype = ' u1' )
955
- object val
956
970
float64_t fval
957
971
958
972
for i in range (n):
@@ -962,21 +976,23 @@ def maybe_convert_numeric(ndarray[object] values, set na_values,
962
976
seen.saw_null()
963
977
floats[i] = complexes[i] = nan
964
978
elif util.is_float_object(val):
965
- if val != val:
979
+ fval = val
980
+ if fval != fval:
966
981
seen.null_ = True
967
982
968
- floats[i] = complexes[i] = val
983
+ floats[i] = complexes[i] = fval
969
984
seen.float_ = True
970
985
elif util.is_integer_object(val):
971
986
floats[i] = complexes[i] = val
972
987
973
- as_int = int (val)
974
- seen.saw_int(as_int)
988
+ val = int (val)
989
+ seen.saw_int(val)
990
+
991
+ if val >= 0 :
992
+ uints[i] = val
975
993
976
- if as_int >= 0 :
977
- uints[i] = as_int
978
- if as_int <= iINT64_MAX:
979
- ints[i] = as_int
994
+ if val <= oINT64_MAX:
995
+ ints[i] = val
980
996
elif util.is_bool_object(val):
981
997
floats[i] = uints[i] = ints[i] = bools[i] = val
982
998
seen.bool_ = True
@@ -1017,12 +1033,12 @@ def maybe_convert_numeric(ndarray[object] values, set na_values,
1017
1033
seen.saw_int(as_int)
1018
1034
1019
1035
if not (seen.float_ or as_int in na_values):
1020
- if as_int < iINT64_MIN or as_int > iUINT64_MAX :
1036
+ if as_int < oINT64_MIN or as_int > oUINT64_MAX :
1021
1037
raise ValueError (' Integer out of range.' )
1022
1038
1023
1039
if as_int >= 0 :
1024
1040
uints[i] = as_int
1025
- if as_int <= iINT64_MAX :
1041
+ if as_int <= oINT64_MAX :
1026
1042
ints[i] = as_int
1027
1043
else :
1028
1044
seen.float_ = True
@@ -1053,6 +1069,8 @@ def maybe_convert_numeric(ndarray[object] values, set na_values,
1053
1069
return ints
1054
1070
1055
1071
1072
+ @ cython.boundscheck (False )
1073
+ @ cython.wraparound (False )
1056
1074
def maybe_convert_objects (ndarray[object] objects , bint try_float = 0 ,
1057
1075
bint safe = 0 , bint convert_datetime = 0 ,
1058
1076
bint convert_timedelta = 0 ):
0 commit comments