-
-
Notifications
You must be signed in to change notification settings - Fork 18.4k
Accepts integer/float string with units and raises when unit is ambiguous (2) #23025
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 36 commits
ab5f7ba
7a38ecd
a65a35a
57dea1d
b8cf952
8154859
a90a992
1184b6e
5e28b49
fafe838
3ca0dae
8105f9c
e90a18b
e0a55a8
827aebf
9bff504
b6c7d45
9ff6ade
be93e4b
85f0103
673ad19
eb7d3f8
bb40f77
2e331c1
bada4a7
8c0425a
493a14b
e525ec4
448b68a
bd173a9
d16c4c5
1cfc729
e559f06
b914950
64a4440
4d26474
db41054
2f53004
fb40c94
f5e59ee
e7266da
b6a02df
694abe9
4d86ae1
40b09f4
a9c4675
95302de
661fd70
80a1161
dbe8fae
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -165,6 +165,8 @@ cpdef convert_to_timedelta64(object ts, object unit): | |
# kludgy here until we have a timedelta scalar | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. you can make There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sorry, what should I add to the docstring exactly? |
||
# handle the numpy < 1.7 case | ||
""" | ||
if unit is None: | ||
unit = 'ns' | ||
if checknull_with_nat(ts): | ||
return np.timedelta64(NPY_NAT) | ||
elif isinstance(ts, Timedelta): | ||
|
@@ -214,7 +216,7 @@ cpdef convert_to_timedelta64(object ts, object unit): | |
|
||
@cython.boundscheck(False) | ||
@cython.wraparound(False) | ||
def array_to_timedelta64(object[:] values, unit='ns', errors='raise'): | ||
def array_to_timedelta64(object[:] values, unit=None, errors='raise'): | ||
""" | ||
Convert an ndarray to an array of timedeltas. If errors == 'coerce', | ||
coerce non-convertible objects to NaT. Otherwise, raise. | ||
|
@@ -237,7 +239,7 @@ def array_to_timedelta64(object[:] values, unit='ns', errors='raise'): | |
# this is where all of the error handling will take place. | ||
try: | ||
for i in range(n): | ||
result[i] = parse_timedelta_string(values[i]) | ||
result[i] = parse_timedelta_string(values[i], specified_unit=unit) | ||
except: | ||
unit = parse_timedelta_unit(unit) | ||
for i in range(n): | ||
|
@@ -313,7 +315,7 @@ cdef inline _decode_if_necessary(object ts): | |
return ts | ||
|
||
|
||
cdef inline parse_timedelta_string(object ts): | ||
cpdef inline parse_timedelta_string(object ts, specified_unit=None): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jreback said:
I think differently I would like to present the reasons why I think this is the proper place:
If we don't leave the responsibility of checking units for string in
The way it is right now we just give it the externally provided units and it can now do the checks itself - and that's all, and all cases are covered. Very little coding needed. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can you rename this to just There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The other There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ok |
||
""" | ||
Parse a regular format timedelta string. Return an int64_t (in ns) | ||
or raise a ValueError on an invalid parse. | ||
|
@@ -427,6 +429,17 @@ cdef inline parse_timedelta_string(object ts): | |
have_value = 1 | ||
have_dot = 0 | ||
|
||
# Consider units from outside | ||
if not unit: | ||
if specified_unit: | ||
unit = [specified_unit] | ||
else: | ||
if specified_unit: | ||
raise ValueError( | ||
"units were doubly specified, both as an argument ({})" | ||
" and inside string ({})".format(specified_unit, unit) | ||
) | ||
|
||
# we had a dot, but we have a fractional | ||
# value since we have an unit | ||
if have_dot and len(unit): | ||
|
@@ -468,14 +481,12 @@ cdef inline parse_timedelta_string(object ts): | |
else: | ||
raise ValueError("unit abbreviation w/o a number") | ||
|
||
# treat as nanoseconds | ||
# but only if we don't have anything else | ||
# raise if we just have a number without units | ||
else: | ||
if have_value: | ||
raise ValueError("have leftover units") | ||
if len(number): | ||
r = timedelta_from_spec(number, frac, 'ns') | ||
result += timedelta_as_neg(r, neg) | ||
raise ValueError("number string without units") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I mentioned it before, but I think we need to deprecate this first. We can here raise a deprecation warning when unit is None, and still fallback to unit='ns' for now There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok! |
||
|
||
return result | ||
|
||
|
@@ -524,10 +535,9 @@ cpdef inline object parse_timedelta_unit(object unit): | |
---------- | ||
unit : an unit string | ||
""" | ||
if unit is None: | ||
return 'ns' | ||
elif unit == 'M': | ||
if unit is None or unit == 'M': | ||
return unit | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jbrockmendel just explaining some changes to previous code so you can review, here I am leaving unit untouched if There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes this is ok, can you add a comment |
||
|
||
try: | ||
return timedelta_abbrevs[unit.lower()] | ||
except (KeyError, AttributeError): | ||
|
@@ -1156,7 +1166,7 @@ class Timedelta(_Timedelta): | |
if len(value) > 0 and value[0] == 'P': | ||
value = parse_iso_format_string(value) | ||
else: | ||
value = parse_timedelta_string(value) | ||
value = parse_timedelta_string(value, specified_unit=unit) | ||
value = np.timedelta64(value) | ||
elif PyDelta_Check(value): | ||
value = convert_to_timedelta64(value, 'ns') | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also mention
to_timedelta
, and also the change thatunit
now needs to be specified?