|
20 | 20 | is_dtype_equal,
|
21 | 21 | is_float_dtype, is_complex_dtype,
|
22 | 22 | is_integer_dtype,
|
| 23 | + is_unsigned_integer_dtype, |
23 | 24 | is_datetime_or_timedelta_dtype,
|
24 | 25 | is_bool_dtype, is_scalar,
|
25 | 26 | is_string_dtype, _string_dtypes,
|
@@ -1269,3 +1270,74 @@ def construct_1d_ndarray_preserving_na(values, dtype=None, copy=False):
|
1269 | 1270 | subarr = subarr2
|
1270 | 1271 |
|
1271 | 1272 | return subarr
|
| 1273 | + |
| 1274 | + |
| 1275 | +def maybe_cast_to_integer_array(arr, dtype, copy=False): |
| 1276 | + """ |
| 1277 | + Takes any dtype and returns the casted version, raising for when data is |
| 1278 | + incompatible with integer/unsigned integer dtypes. |
| 1279 | +
|
| 1280 | + .. versionadded:: 0.24.0 |
| 1281 | +
|
| 1282 | + Parameters |
| 1283 | + ---------- |
| 1284 | + arr : array-like |
| 1285 | + The array to cast. |
| 1286 | + dtype : str, np.dtype |
| 1287 | + The integer dtype to cast the array to. |
| 1288 | + copy: boolean, default False |
| 1289 | + Whether to make a copy of the array before returning. |
| 1290 | +
|
| 1291 | + Returns |
| 1292 | + ------- |
| 1293 | + int_arr : ndarray |
| 1294 | + An array of integer or unsigned integer dtype |
| 1295 | +
|
| 1296 | + Raises |
| 1297 | + ------ |
| 1298 | + OverflowError : the dtype is incompatible with the data |
| 1299 | + ValueError : loss of precision has occurred during casting |
| 1300 | +
|
| 1301 | + Examples |
| 1302 | + -------- |
| 1303 | + If you try to coerce negative values to unsigned integers, it raises: |
| 1304 | +
|
| 1305 | + >>> Series([-1], dtype="uint64") |
| 1306 | + Traceback (most recent call last): |
| 1307 | + ... |
| 1308 | + OverflowError: Trying to coerce negative values to unsigned integers |
| 1309 | +
|
| 1310 | + Also, if you try to coerce float values to integers, it raises: |
| 1311 | +
|
| 1312 | + >>> Series([1, 2, 3.5], dtype="int64") |
| 1313 | + Traceback (most recent call last): |
| 1314 | + ... |
| 1315 | + ValueError: Trying to coerce float values to integers |
| 1316 | + """ |
| 1317 | + |
| 1318 | + try: |
| 1319 | + if not hasattr(arr, "astype"): |
| 1320 | + casted = np.array(arr, dtype=dtype, copy=copy) |
| 1321 | + else: |
| 1322 | + casted = arr.astype(dtype, copy=copy) |
| 1323 | + except OverflowError: |
| 1324 | + raise OverflowError("The elements provided in the data cannot all be " |
| 1325 | + "casted to the dtype {dtype}".format(dtype=dtype)) |
| 1326 | + |
| 1327 | + if np.array_equal(arr, casted): |
| 1328 | + return casted |
| 1329 | + |
| 1330 | + # We do this casting to allow for proper |
| 1331 | + # data and dtype checking. |
| 1332 | + # |
| 1333 | + # We didn't do this earlier because NumPy |
| 1334 | + # doesn't handle `uint64` correctly. |
| 1335 | + arr = np.asarray(arr) |
| 1336 | + |
| 1337 | + if is_unsigned_integer_dtype(dtype) and (arr < 0).any(): |
| 1338 | + raise OverflowError("Trying to coerce negative values " |
| 1339 | + "to unsigned integers") |
| 1340 | + |
| 1341 | + if is_integer_dtype(dtype) and (is_float_dtype(arr) or |
| 1342 | + is_object_dtype(arr)): |
| 1343 | + raise ValueError("Trying to coerce float values to integers") |
0 commit comments