0

Problem

I don't like the way Pandas displays timedelta because

  • There are too many digits behind the decimal point
  • "days" could be spelled "d"

How do I make all timedeltas in a DataFrame display according to my custom format? E.g.

timedelta(days=34, hours=7, seconds=33.7) -> "34d 07:00:34"

and

timedelta(hours=7, seconds=4) -> "07:00:04" (right aligned)

Here's what didn't help:

  • Adding the datetime.min + mytimedelta.strftime("%jd %H:%M%D") (source) This works for the time but for the days it's one off.
  • I couldn't find a useful option in the pandas display options.
  • with pd.option_context("display.precision", 0): which should solve the decimals problem is ignored for timedeltas.

Here's how to format a single time delta

(source)

td = timedelta(days=34, hours=7, seconds=33.7)
days = td.days
hours, minutes = divmod(td.seconds, 3600)
minutes, seconds = divmod(minutes, 60)
seconds += td.microseconds > 5e5
f"{days}d {hours:02}:{minutes:02}:{seconds:02}"

MCVE for playing around:

from datetime import timedelta
df = pd.DataFrame([
    ["short", timedelta(seconds=15.4), timedelta(hours=7, seconds=4)],
    ["long", timedelta(days=34, hours=7, seconds=4), timedelta(days=2)]
])
print(df)

       0                      1               2
0  short 0 days 00:00:15.400000 0 days 07:00:04
1   long       34 days 07:00:04 2 days 00:00:00

myprettyprint(df)  # doesn't exist yet

       0             1            2
0  short      00:00:15  0d 07:00:04
1   long  34d 07:00:04  2d 00:00:00
Joooeey
  • 3,394
  • 1
  • 35
  • 49

1 Answers1

0

That's what pandas.DataFrame.to_string is for:

def timedelta_to_string(self):
    """Custom string formatting for timedelta."""
    days = self.days
    hours, minutes = divmod(self.seconds, 3600)
    minutes, seconds = divmod(minutes, 60)
    seconds += self.microseconds > 5e5
    return f"{days}d {hours:02}:{minutes:02}:{seconds:02}"

print(df.to_string(
    formatters=dict.fromkeys([1, 2], timedelta_to_string)
))

       0            1           2
0  short  0d 00:00:15 0d 07:00:04
1   long 34d 07:00:04 2d 00:00:00
Joooeey
  • 3,394
  • 1
  • 35
  • 49