@@ -22,6 +22,28 @@ class NumericIndex(Index):
2222 """
2323 _is_numeric_dtype = True
2424
25+ def __new__ (cls , data = None , dtype = None , copy = False , name = None ,
26+ fastpath = False ):
27+
28+ if fastpath :
29+ return cls ._simple_new (data , name = name )
30+
31+ # isscalar, generators handled in coerce_to_ndarray
32+ data = cls ._coerce_to_ndarray (data )
33+
34+ if issubclass (data .dtype .type , compat .string_types ):
35+ cls ._string_data_error (data )
36+
37+ if copy or not com .is_dtype_equal (data .dtype , cls ._default_dtype ):
38+ subarr = np .array (data , dtype = cls ._default_dtype , copy = copy )
39+ cls ._assert_safe_casting (data , subarr )
40+ else :
41+ subarr = data
42+
43+ if name is None and hasattr (data , 'name' ):
44+ name = data .name
45+ return cls ._simple_new (subarr , name = name )
46+
2547 def _maybe_cast_slice_bound (self , label , side , kind ):
2648 """
2749 This function should be overloaded in subclasses that allow non-trivial
@@ -55,6 +77,15 @@ def _convert_tolerance(self, tolerance):
5577 raise ValueError ('tolerance argument for %s must be numeric: %r' %
5678 (type (self ).__name__ , tolerance ))
5779
80+ @classmethod
81+ def _assert_safe_casting (cls , data , subarr ):
82+ """
83+ Subclasses need to override this only if the process of casting data
84+ from some accepted dtype to the internal dtype(s) bears the risk of
85+ truncation (e.g. float to int).
86+ """
87+ pass
88+
5889
5990class Int64Index (NumericIndex ):
6091 """
@@ -90,29 +121,7 @@ class Int64Index(NumericIndex):
90121
91122 _engine_type = _index .Int64Engine
92123
93- def __new__ (cls , data = None , dtype = None , copy = False , name = None ,
94- fastpath = False , ** kwargs ):
95-
96- if fastpath :
97- return cls ._simple_new (data , name = name )
98-
99- # isscalar, generators handled in coerce_to_ndarray
100- data = cls ._coerce_to_ndarray (data )
101-
102- if issubclass (data .dtype .type , compat .string_types ):
103- cls ._string_data_error (data )
104-
105- elif issubclass (data .dtype .type , np .integer ):
106- dtype = np .int64
107- subarr = np .array (data , dtype = dtype , copy = copy )
108- else :
109- subarr = np .array (data , dtype = np .int64 , copy = copy )
110- if len (data ) > 0 :
111- if (subarr != data ).any ():
112- raise TypeError ('Unsafe NumPy casting to integer, you must'
113- ' explicitly cast' )
114-
115- return cls ._simple_new (subarr , name = name )
124+ _default_dtype = np .int64
116125
117126 @property
118127 def inferred_type (self ):
@@ -166,6 +175,15 @@ def _wrap_joined_index(self, joined, other):
166175 name = self .name if self .name == other .name else None
167176 return Int64Index (joined , name = name )
168177
178+ @classmethod
179+ def _assert_safe_casting (cls , data , subarr ):
180+ """
181+ Ensure incoming data can be represented as ints.
182+ """
183+ if not issubclass (data .dtype .type , np .integer ):
184+ if not np .array_equal (data , subarr ):
185+ raise TypeError ('Unsafe NumPy casting, you must '
186+ 'explicitly cast' )
169187
170188Int64Index ._add_numeric_methods ()
171189Int64Index ._add_logical_methods ()
@@ -200,39 +218,7 @@ class Float64Index(NumericIndex):
200218 _inner_indexer = _algos .inner_join_indexer_float64
201219 _outer_indexer = _algos .outer_join_indexer_float64
202220
203- def __new__ (cls , data = None , dtype = None , copy = False , name = None ,
204- fastpath = False , ** kwargs ):
205-
206- if fastpath :
207- return cls ._simple_new (data , name )
208-
209- data = cls ._coerce_to_ndarray (data )
210-
211- if issubclass (data .dtype .type , compat .string_types ):
212- cls ._string_data_error (data )
213-
214- if dtype is None :
215- dtype = np .float64
216- dtype = np .dtype (dtype )
217-
218- # allow integer / object dtypes to be passed, but coerce to float64
219- if dtype .kind in ['i' , 'O' , 'f' ]:
220- dtype = np .float64
221-
222- else :
223- raise TypeError ("cannot support {0} dtype in "
224- "Float64Index" .format (dtype ))
225-
226- try :
227- subarr = np .array (data , dtype = dtype , copy = copy )
228- except :
229- raise TypeError ('Unsafe NumPy casting, you must explicitly cast' )
230-
231- # coerce to float64 for storage
232- if subarr .dtype != np .float64 :
233- subarr = subarr .astype (np .float64 )
234-
235- return cls ._simple_new (subarr , name )
221+ _default_dtype = np .float64
236222
237223 @property
238224 def inferred_type (self ):
@@ -392,6 +378,5 @@ def isin(self, values, level=None):
392378 return lib .ismember_nans (np .array (self ), value_set ,
393379 isnull (list (value_set )).any ())
394380
395-
396381Float64Index ._add_numeric_methods ()
397382Float64Index ._add_logical_methods_disabled ()
0 commit comments