|
1 |
| -import warnings |
2 |
| - |
3 |
| -from pandas.util._exceptions import find_stack_level |
4 |
| - |
5 | 1 | cimport cython
|
6 | 2 |
|
7 | 3 | from datetime import timezone
|
@@ -234,117 +230,6 @@ def format_array_from_datetime(
|
234 | 230 | return result
|
235 | 231 |
|
236 | 232 |
|
237 |
| -def array_with_unit_to_datetime( |
238 |
| - ndarray[object] values, |
239 |
| - str unit, |
240 |
| - str errors="coerce" |
241 |
| -): |
242 |
| - """ |
243 |
| - Convert the ndarray to datetime according to the time unit. |
244 |
| -
|
245 |
| - This function converts an array of objects into a numpy array of |
246 |
| - datetime64[ns]. It returns the converted array |
247 |
| - and also returns the timezone offset |
248 |
| -
|
249 |
| - if errors: |
250 |
| - - raise: return converted values or raise OutOfBoundsDatetime |
251 |
| - if out of range on the conversion or |
252 |
| - ValueError for other conversions (e.g. a string) |
253 |
| - - ignore: return non-convertible values as the same unit |
254 |
| - - coerce: NaT for non-convertibles |
255 |
| -
|
256 |
| - Parameters |
257 |
| - ---------- |
258 |
| - values : ndarray |
259 |
| - Date-like objects to convert. |
260 |
| - unit : str |
261 |
| - Time unit to use during conversion. |
262 |
| - errors : str, default 'raise' |
263 |
| - Error behavior when parsing. |
264 |
| -
|
265 |
| - Returns |
266 |
| - ------- |
267 |
| - result : ndarray of m8 values |
268 |
| - tz : parsed timezone offset or None |
269 |
| - """ |
270 |
| - cdef: |
271 |
| - Py_ssize_t i, n=len(values) |
272 |
| - bint is_coerce = errors == "coerce" |
273 |
| - bint is_raise = errors == "raise" |
274 |
| - ndarray[int64_t] iresult |
275 |
| - tzinfo tz = None |
276 |
| - double fval |
277 |
| - |
278 |
| - assert is_coerce or is_raise |
279 |
| - |
280 |
| - if unit == "ns": |
281 |
| - result, tz = array_to_datetime( |
282 |
| - values.astype(object, copy=False), |
283 |
| - errors=errors, |
284 |
| - creso=NPY_FR_ns, |
285 |
| - ) |
286 |
| - return result, tz |
287 |
| - |
288 |
| - result = np.empty(n, dtype="M8[ns]") |
289 |
| - iresult = result.view("i8") |
290 |
| - |
291 |
| - for i in range(n): |
292 |
| - val = values[i] |
293 |
| - |
294 |
| - try: |
295 |
| - if checknull_with_nat_and_na(val): |
296 |
| - iresult[i] = NPY_NAT |
297 |
| - |
298 |
| - elif is_integer_object(val) or is_float_object(val): |
299 |
| - |
300 |
| - if val != val or val == NPY_NAT: |
301 |
| - iresult[i] = NPY_NAT |
302 |
| - else: |
303 |
| - iresult[i] = cast_from_unit(val, unit) |
304 |
| - |
305 |
| - elif isinstance(val, str): |
306 |
| - if len(val) == 0 or val in nat_strings: |
307 |
| - iresult[i] = NPY_NAT |
308 |
| - |
309 |
| - else: |
310 |
| - |
311 |
| - try: |
312 |
| - fval = float(val) |
313 |
| - except ValueError: |
314 |
| - raise ValueError( |
315 |
| - f"non convertible value {val} with the unit '{unit}'" |
316 |
| - ) |
317 |
| - warnings.warn( |
318 |
| - "The behavior of 'to_datetime' with 'unit' when parsing " |
319 |
| - "strings is deprecated. In a future version, strings will " |
320 |
| - "be parsed as datetime strings, matching the behavior " |
321 |
| - "without a 'unit'. To retain the old behavior, explicitly " |
322 |
| - "cast ints or floats to numeric type before calling " |
323 |
| - "to_datetime.", |
324 |
| - FutureWarning, |
325 |
| - stacklevel=find_stack_level(), |
326 |
| - ) |
327 |
| - |
328 |
| - iresult[i] = cast_from_unit(fval, unit) |
329 |
| - |
330 |
| - else: |
331 |
| - # TODO: makes more sense as TypeError, but that would be an |
332 |
| - # API change. |
333 |
| - raise ValueError( |
334 |
| - f"unit='{unit}' not valid with non-numerical val='{val}'" |
335 |
| - ) |
336 |
| - |
337 |
| - except (ValueError, TypeError) as err: |
338 |
| - if is_raise: |
339 |
| - err.args = (f"{err}, at position {i}",) |
340 |
| - raise |
341 |
| - else: |
342 |
| - # is_coerce |
343 |
| - iresult[i] = NPY_NAT |
344 |
| - |
345 |
| - return result, tz |
346 |
| - |
347 |
| - |
348 | 233 | @cython.wraparound(False)
|
349 | 234 | @cython.boundscheck(False)
|
350 | 235 | def first_non_null(values: ndarray) -> int:
|
@@ -376,6 +261,7 @@ cpdef array_to_datetime(
|
376 | 261 | bint yearfirst=False,
|
377 | 262 | bint utc=False,
|
378 | 263 | NPY_DATETIMEUNIT creso=NPY_FR_ns,
|
| 264 | + str unit_for_numerics=None, |
379 | 265 | ):
|
380 | 266 | """
|
381 | 267 | Converts a 1D array of date-like values to a numpy array of either:
|
@@ -404,6 +290,7 @@ cpdef array_to_datetime(
|
404 | 290 | indicator whether the dates should be UTC
|
405 | 291 | creso : NPY_DATETIMEUNIT, default NPY_FR_ns
|
406 | 292 | Set to NPY_FR_GENERIC to infer a resolution.
|
| 293 | + unit_for_numerics : str, default "ns" |
407 | 294 |
|
408 | 295 | Returns
|
409 | 296 | -------
|
@@ -434,6 +321,13 @@ cpdef array_to_datetime(
|
434 | 321 | abbrev = "ns"
|
435 | 322 | else:
|
436 | 323 | abbrev = npy_unit_to_abbrev(creso)
|
| 324 | + |
| 325 | + if unit_for_numerics is not None: |
| 326 | + # either creso or unit_for_numerics should be passed, not both |
| 327 | + assert creso == NPY_FR_ns |
| 328 | + else: |
| 329 | + unit_for_numerics = abbrev |
| 330 | + |
437 | 331 | result = np.empty((<object>values).shape, dtype=f"M8[{abbrev}]")
|
438 | 332 | iresult = result.view("i8").ravel()
|
439 | 333 |
|
@@ -485,7 +379,8 @@ cpdef array_to_datetime(
|
485 | 379 | creso = state.creso
|
486 | 380 |
|
487 | 381 | # we now need to parse this as if unit=abbrev
|
488 |
| - iresult[i] = cast_from_unit(val, abbrev, out_reso=creso) |
| 382 | + iresult[i] = cast_from_unit(val, unit_for_numerics, out_reso=creso) |
| 383 | + |
489 | 384 | state.found_other = True
|
490 | 385 |
|
491 | 386 | elif isinstance(val, str):
|
|
0 commit comments