Coverage for /var/srv/projects/api.amasfac.comuna18.com/tmp/venv/lib/python3.9/site-packages/pandas/core/tools/numeric.py: 7%

84 statements  

« prev     ^ index     » next       coverage.py v6.4.4, created at 2023-07-17 14:22 -0600

1from __future__ import annotations 

2 

3import numpy as np 

4 

5from pandas._libs import lib 

6from pandas._typing import npt 

7 

8from pandas.core.dtypes.cast import maybe_downcast_numeric 

9from pandas.core.dtypes.common import ( 

10 ensure_object, 

11 is_datetime_or_timedelta_dtype, 

12 is_decimal, 

13 is_integer_dtype, 

14 is_number, 

15 is_numeric_dtype, 

16 is_scalar, 

17 needs_i8_conversion, 

18) 

19from pandas.core.dtypes.generic import ( 

20 ABCIndex, 

21 ABCSeries, 

22) 

23 

24import pandas as pd 

25from pandas.core.arrays.numeric import NumericArray 

26 

27 

28def to_numeric(arg, errors="raise", downcast=None): 

29 """ 

30 Convert argument to a numeric type. 

31 

32 The default return dtype is `float64` or `int64` 

33 depending on the data supplied. Use the `downcast` parameter 

34 to obtain other dtypes. 

35 

36 Please note that precision loss may occur if really large numbers 

37 are passed in. Due to the internal limitations of `ndarray`, if 

38 numbers smaller than `-9223372036854775808` (np.iinfo(np.int64).min) 

39 or larger than `18446744073709551615` (np.iinfo(np.uint64).max) are 

40 passed in, it is very likely they will be converted to float so that 

41 they can stored in an `ndarray`. These warnings apply similarly to 

42 `Series` since it internally leverages `ndarray`. 

43 

44 Parameters 

45 ---------- 

46 arg : scalar, list, tuple, 1-d array, or Series 

47 Argument to be converted. 

48 errors : {'ignore', 'raise', 'coerce'}, default 'raise' 

49 - If 'raise', then invalid parsing will raise an exception. 

50 - If 'coerce', then invalid parsing will be set as NaN. 

51 - If 'ignore', then invalid parsing will return the input. 

52 downcast : str, default None 

53 Can be 'integer', 'signed', 'unsigned', or 'float'. 

54 If not None, and if the data has been successfully cast to a 

55 numerical dtype (or if the data was numeric to begin with), 

56 downcast that resulting data to the smallest numerical dtype 

57 possible according to the following rules: 

58 

59 - 'integer' or 'signed': smallest signed int dtype (min.: np.int8) 

60 - 'unsigned': smallest unsigned int dtype (min.: np.uint8) 

61 - 'float': smallest float dtype (min.: np.float32) 

62 

63 As this behaviour is separate from the core conversion to 

64 numeric values, any errors raised during the downcasting 

65 will be surfaced regardless of the value of the 'errors' input. 

66 

67 In addition, downcasting will only occur if the size 

68 of the resulting data's dtype is strictly larger than 

69 the dtype it is to be cast to, so if none of the dtypes 

70 checked satisfy that specification, no downcasting will be 

71 performed on the data. 

72 

73 Returns 

74 ------- 

75 ret 

76 Numeric if parsing succeeded. 

77 Return type depends on input. Series if Series, otherwise ndarray. 

78 

79 See Also 

80 -------- 

81 DataFrame.astype : Cast argument to a specified dtype. 

82 to_datetime : Convert argument to datetime. 

83 to_timedelta : Convert argument to timedelta. 

84 numpy.ndarray.astype : Cast a numpy array to a specified type. 

85 DataFrame.convert_dtypes : Convert dtypes. 

86 

87 Examples 

88 -------- 

89 Take separate series and convert to numeric, coercing when told to 

90 

91 >>> s = pd.Series(['1.0', '2', -3]) 

92 >>> pd.to_numeric(s) 

93 0 1.0 

94 1 2.0 

95 2 -3.0 

96 dtype: float64 

97 >>> pd.to_numeric(s, downcast='float') 

98 0 1.0 

99 1 2.0 

100 2 -3.0 

101 dtype: float32 

102 >>> pd.to_numeric(s, downcast='signed') 

103 0 1 

104 1 2 

105 2 -3 

106 dtype: int8 

107 >>> s = pd.Series(['apple', '1.0', '2', -3]) 

108 >>> pd.to_numeric(s, errors='ignore') 

109 0 apple 

110 1 1.0 

111 2 2 

112 3 -3 

113 dtype: object 

114 >>> pd.to_numeric(s, errors='coerce') 

115 0 NaN 

116 1 1.0 

117 2 2.0 

118 3 -3.0 

119 dtype: float64 

120 

121 Downcasting of nullable integer and floating dtypes is supported: 

122 

123 >>> s = pd.Series([1, 2, 3], dtype="Int64") 

124 >>> pd.to_numeric(s, downcast="integer") 

125 0 1 

126 1 2 

127 2 3 

128 dtype: Int8 

129 >>> s = pd.Series([1.0, 2.1, 3.0], dtype="Float64") 

130 >>> pd.to_numeric(s, downcast="float") 

131 0 1.0 

132 1 2.1 

133 2 3.0 

134 dtype: Float32 

135 """ 

136 if downcast not in (None, "integer", "signed", "unsigned", "float"): 

137 raise ValueError("invalid downcasting method provided") 

138 

139 if errors not in ("ignore", "raise", "coerce"): 

140 raise ValueError("invalid error value specified") 

141 

142 is_series = False 

143 is_index = False 

144 is_scalars = False 

145 

146 if isinstance(arg, ABCSeries): 

147 is_series = True 

148 values = arg.values 

149 elif isinstance(arg, ABCIndex): 

150 is_index = True 

151 if needs_i8_conversion(arg.dtype): 

152 values = arg.asi8 

153 else: 

154 values = arg.values 

155 elif isinstance(arg, (list, tuple)): 

156 values = np.array(arg, dtype="O") 

157 elif is_scalar(arg): 

158 if is_decimal(arg): 

159 return float(arg) 

160 if is_number(arg): 

161 return arg 

162 is_scalars = True 

163 values = np.array([arg], dtype="O") 

164 elif getattr(arg, "ndim", 1) > 1: 

165 raise TypeError("arg must be a list, tuple, 1-d array, or Series") 

166 else: 

167 values = arg 

168 

169 # GH33013: for IntegerArray & FloatingArray extract non-null values for casting 

170 # save mask to reconstruct the full array after casting 

171 mask: npt.NDArray[np.bool_] | None = None 

172 if isinstance(values, NumericArray): 

173 mask = values._mask 

174 values = values._data[~mask] 

175 

176 values_dtype = getattr(values, "dtype", None) 

177 if is_numeric_dtype(values_dtype): 

178 pass 

179 elif is_datetime_or_timedelta_dtype(values_dtype): 

180 values = values.view(np.int64) 

181 else: 

182 values = ensure_object(values) 

183 coerce_numeric = errors not in ("ignore", "raise") 

184 try: 

185 values, _ = lib.maybe_convert_numeric( 

186 values, set(), coerce_numeric=coerce_numeric 

187 ) 

188 except (ValueError, TypeError): 

189 if errors == "raise": 

190 raise 

191 

192 # attempt downcast only if the data has been successfully converted 

193 # to a numerical dtype and if a downcast method has been specified 

194 if downcast is not None and is_numeric_dtype(values.dtype): 

195 typecodes: str | None = None 

196 

197 if downcast in ("integer", "signed"): 

198 typecodes = np.typecodes["Integer"] 

199 elif downcast == "unsigned" and (not len(values) or np.min(values) >= 0): 

200 typecodes = np.typecodes["UnsignedInteger"] 

201 elif downcast == "float": 

202 typecodes = np.typecodes["Float"] 

203 

204 # pandas support goes only to np.float32, 

205 # as float dtypes smaller than that are 

206 # extremely rare and not well supported 

207 float_32_char = np.dtype(np.float32).char 

208 float_32_ind = typecodes.index(float_32_char) 

209 typecodes = typecodes[float_32_ind:] 

210 

211 if typecodes is not None: 

212 # from smallest to largest 

213 for typecode in typecodes: 

214 dtype = np.dtype(typecode) 

215 if dtype.itemsize <= values.dtype.itemsize: 

216 values = maybe_downcast_numeric(values, dtype) 

217 

218 # successful conversion 

219 if values.dtype == dtype: 

220 break 

221 

222 # GH33013: for IntegerArray & FloatingArray need to reconstruct masked array 

223 if mask is not None: 

224 data = np.zeros(mask.shape, dtype=values.dtype) 

225 data[~mask] = values 

226 

227 from pandas.core.arrays import ( 

228 FloatingArray, 

229 IntegerArray, 

230 ) 

231 

232 klass = IntegerArray if is_integer_dtype(data.dtype) else FloatingArray 

233 values = klass(data, mask.copy()) 

234 

235 if is_series: 

236 return arg._constructor(values, index=arg.index, name=arg.name) 

237 elif is_index: 

238 # because we want to coerce to numeric if possible, 

239 # do not use _shallow_copy 

240 return pd.Index(values, name=arg.name) 

241 elif is_scalars: 

242 return values[0] 

243 else: 

244 return values