Skip to content
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

TimedeltaIndex should have a method to help to convert to string (with a custom format with microsecond resolution) #26897

Open
scls19fr opened this issue Jun 17, 2019 · 3 comments
Labels
Enhancement Needs Discussion Requires discussion from core team before further action Timedelta Timedelta data type

Comments

@scls19fr
Copy link
Contributor

scls19fr commented Jun 17, 2019

Hello,

I noticed in doc https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.dt.strftime.html that DatetimeIndex have a dt attribute which can help to convert a Timestamp to string.

>>> rng = pd.date_range(pd.Timestamp("2018-03-10 09:00"),
...                     periods=3, freq='s')
>>> rng.strftime('%B %d, %Y, %r')
Index(['March 10, 2018, 09:00:00 AM', 'March 10, 2018, 09:00:01 AM',
       'March 10, 2018, 09:00:02 AM'],
      dtype='object')

(or rng.to_series().dt.strftime('%B %d, %Y, %r'))

A similar method should exist for TimedeltaIndex to help to convert it to string (it's especially useful to output an Excel files without "0 days" for each index when each timedelta is below 1 day)

>>> rng = pd.timedelta_range(start="0h", freq="15min", periods=3)
TimedeltaIndex(['00:00:00', '00:15:00', '00:30:00'], dtype='timedelta64[ns]', freq='15T')
>>> rng.dt.strftime("%M:%S")
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-48-1f408f75ecf6> in <module>
----> 1 rng.dt.strftime("%m:%s")

AttributeError: 'TimedeltaIndex' object has no attribute 'dt'

I have found a bad method to do this:

rng.map(lambda td: time.strftime("%M:%S", time.gmtime((td.to_pytimedelta().total_seconds()))))

unfortunatelly it doesn't support the "f" specifier for microsecond (I only need in fact millisecond)

>>> rng = pd.to_timedelta(["00:01:02.345", "00:02:03.456"])
TimedeltaIndex(['00:01:02.345000', '00:02:03.456000'], dtype='timedelta64[ns]', freq=None)
>>> rng.map(lambda td: time.strftime("%M:%S.%f", time.gmtime((td.to_pytimedelta().total_seconds()))))
Index(['01:02.f', '02:03.f'], dtype='object')

it could be nice to simply be able to do

rng.to_series().dt.strftime("%M:%S.%f")

or naming attribute td (instead of dt) to avoid confusion between DatetimeIndex and TimedeltaIndex

rng.to_series().td.strftime("%M:%S.%f")

or even simplier

rng.strftime("%M:%S.%f")

I think a workaround to achieve this is (with positive Timedelta) to add epoch and so manage Timestamp instead.

>>> rng = pd.to_timedelta(["00:01:02.345", "00:02:03.456"])
TimedeltaIndex(['00:01:02.345000', '00:02:03.456000'], dtype='timedelta64[ns]', freq=None)
>>> rng = rng + pd.to_datetime(0)
DatetimeIndex(['1970-01-01 00:01:02.345000', '1970-01-01 00:02:03.456000'], dtype='datetime64[ns]', freq=None)
rng = rng.strftime("%H:%M.%f")
Index(['00:01.345000', '00:02.456000'], dtype='object')
>>> rng.str[:-3]
Index(['00:01.345', '00:02.456'], dtype='object')

But I'm still wondering how to manage negative Timedelta such as

>>> rng = pd.to_timedelta(["00:01:02.345", "-00:02:03.456"])
TimedeltaIndex(['00:01:02.345000', '-1 days +23:57:56.544000'], dtype='timedelta64[ns]', freq=None)

Any idea?

Kind regards

PS : related issue #17232 (about display of negative Timedelta)

@scls19fr scls19fr changed the title TimedeltaIndex should have a method to help to convert to string (with a custom format with microsecond resolution)) TimedeltaIndex should have a method to help to convert to string (with a custom format with microsecond resolution) Jun 17, 2019
@mroeschke
Copy link
Member

We mirror standard library methods in the datetime module, and since there isn't a timedelta.strftime, I'd be inclined to have this method named differently.

@scls19fr
Copy link
Contributor Author

scls19fr commented Jun 17, 2019

Maybe strfdelta like mentioned in https://stackoverflow.com/questions/8906926/formatting-python-timedelta-objects could be a good method name candidate

@scls19fr
Copy link
Contributor Author

Given that a Timedelta can be positive or negative (contrary to Timestamp), a special code for sign should be defined.

See http://strftime.org/ for reference about Python's strftime directives (on which we should get inspiration for a strfdelta implementation)

In fact we should even have 2 codes for sign

  • one which should be replaced by + or - (depending on Timedelta sign)
  • an other one which should be replaced by - (only for negative Timedelta ie positive Timestamp don't have a leading +)

others codes to support should be (at least)

Code Meaning Example
%D number of days (zero padding could be supported using for example %02D) 3 or 003
%DAY Locale’s equivalent of either day or days (singular or plural) day or days
%H Hour (24-hour clock) as a zero-padded decimal number. 07
%-H Hour (24-hour clock) as a decimal number. (Platform specific) 7
%HOUR Locale’s equivalent of either hour or hours (singular or plural) hour or hours
%M Minute as a zero-padded decimal number. 06
%-M Minute as a decimal number. (Platform specific) 6
%S Second as a zero-padded decimal number. 05
%-S Second as a decimal number. (Platform specific) 5
%f Microsecond as a decimal number, zero-padded on the left. 000000

maybe some additional code could be added such as

Code Meaning Example
%MINUTE Locale’s equivalent of either minute or minutes (singular or plural) minute or minutes
%SECOND Locale’s equivalent of either second or seconds (singular or plural) second or seconds
%MICROSECOND Locale’s equivalent of either microsecond or microseconds (singular or plural) microsecond or microseconds

to support locale’s equivalent of minute, second, microsecond (using singular or plural form)

@mroeschke mroeschke added Needs Discussion Requires discussion from core team before further action and removed API Design labels Jul 10, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement Needs Discussion Requires discussion from core team before further action Timedelta Timedelta data type
Projects
None yet
Development

No branches or pull requests

3 participants