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!
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
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)
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.
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
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!
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
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)
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.
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