Join us for the next conference in 2027!
Install *timewarrior-dataframe* using *pipx* for pivot tables of *timewarrior* summaries

Install *timewarrior-dataframe* using *pipx* for pivot tables of *timewarrior* summaries

March 3, 2025

Things to know:

  • Timewarrior (timew) is a command line tool for tracking time.
  • Timewarrior-Dataframe is an extension processes timew export output using the Pandas Python module.

Install

Timewarrior can be installed on recent Ubuntu releases from the apt repositories. It can also be found in a number of other distro’s packaging systems.

# Ubuntu (and/or Debian?)
sudo apt install timewarrior

pipx can be used to install the timewarrior-dataframe’s twdf command from it’s git repository.

pipx install git+https://github.com/alexlyttle/timewarrior-dataframe.git 

Export with “twdf”

Export time tracking data from timewarrior with timew export [:sometimespec] to CSV with twdf as follows.

timew export :lastmonth | twdf --format csv > last_month_hours.csv

Pivot CSV to another time reporting system using Pandas

Assuming we already exported to CSV with twdf called “last_month_hours.csv”, use Python and Pandas to…

  • Pivot the table by tag/day
  • Add days not found in exported data to table
  • Round tags to nearest quarter-hour for each day
import pandas as pd
tw = pd.read_csv("last_month_hours.csv")
output = "last_month_hours.pivot.csv" 

# Create index with all days in month 
month_days = pd.date_range(tw.Date.iloc[0], tw.Date.iloc[-1], freq="1D").strftime("%Y-%m-%d")

# Sum up by tag each day
tw = tw[["Date", "Tags", "Hours"]].groupby(["Date", "Tags"], as_index=False).sum()  

tw.index = tw.Date
tw = tw.pivot(index="Date", columns="Tags") # Pivot table to read by date and tag
tw = tw.reindex(month_days)                 # Reindex to include all days of month
tw = tw.T                                   # Transpose table to each date a column

tw = 0.25 * ((tw // 0.25) + 1)              # Round hour entries to nearest 15-min

tw.to_csv(output)

I really wish I had the time to contribute those bits of functionality back into the timewarrior-dataframe extension.