printing Timedelta to nanosecond precision

Question:

How can one print directly pandas Timedelta with nanosecond precision? For now, my solution is to add to Timedelta some dummy date to be able to do it. Hopefully, there is a better solution.

import pandas as pd
time = pd.Timedelta(50400001747113)
print(time)
#     0 days 14:00:00.001747
print(pd.Timestamp('2019-10-02') + time)
# 2019-10-02 14:00:00.001747113

You can see that Timestamp is printed up to nanoseconds while Timedelta only to microseconds.

Thank you very much for your help!

Asked By: S.V

||

Answers:

Probably nanoseconds are just not printed, but they are there:

time = pd.Timedelta(50400001747113, unit='ns')
attrs = 'days,seconds,microseconds,nanoseconds'.split(',')
values = [getattr(time, a) for a in attrs]
print(dict(zip(attrs, values)))

Prints:

{'days': 0, 'seconds': 50400, 'microseconds': 1747, 'nanoseconds': 113}

You can easily access nanoseconds via attribute:

>>> time.nanoseconds
113
Answered By: Maurice Meyer

You can access the attributes that you want via named tuple like object:

import pandas as pd
time = pd.Timedelta(50400001747113)
>>> time.components
Components(days=0, hours=14, minutes=0, seconds=0, milliseconds=1, microseconds=747, nanoseconds=113)
Answered By: MyNameIsCaleb

pd.Timedelta.components is NamedTuple-like. Make a format string and pass the Components as a dict.

>>> t
Timedelta('0 days 14:00:00.001747')
>>> fmt = '{days:} days {hours:02}:{minutes:02}:{seconds:02}.{milliseconds:03}{microseconds:03}{nanoseconds:03}'
>>> fmt.format(**t.components._asdict())
'0 days 14:00:00.001747113'
>>> 

Or as you can see in the source, the _repr_base method has a format parameter that you could use.

>>> t._repr_base('all')
'0 days 14:00:00.001747113'

You could also subclass the Pandas.Timedelta and override the `str method.

class MyTD(pd.Timedelta):
    def __str__(self):
        return self._repr_base(format='all')

>>> t = MyTD(50400001747113)
>>> print(t)
0 days 14:00:00.001747113

Given that the single underscore prefix for _repr_base may indicate that it is an implementation detail that could change and pd.Timedelta.components only is NamedTuple-like (whatever that means – does it guarantee a NamedTuple interface?) you could be safe and extract the values from .components and pass them to a format string.

import operator

>>> components = operator.attrgetter('days','hours','minutes','seconds','milliseconds','microseconds','nanoseconds')
>>> fmt = '{} days {:02}:{:02}:{:02}.{:03}{:03}{:03}'
>>> 
>>> t
Timedelta('0 days 14:00:00.001747')
>>> print(fmt.format(*components(t.components)))
0 days 14:00:00.001747113
>>>

That may be being paranoid but I couldn’t find any info along those lines. Maybe someone will chime in.

Answered By: wwii

If you are pre pandas 1.5.0 and dont mind this getting deprecated, you can just call td.delta to get the time in nanoseconds
https://pandas.pydata.org/docs/reference/api/pandas.Timedelta.delta.html

Answered By: ByteMe95