Python: can I convert a datetime to a float with granularity lesser than a whole day?

Viewed 203

I am trying to plot blood pressure readings, each of which has a datetime timestamp with the day and hour:minute:second of the reading.

As many Seaborn regression plots (lmplot, regplot etc) do not support datetime timestamps I resorted to creating a new data frame column with a numeric ordinal like below:

from datetime import date
df['date_ordinal'] = pd.to_datetime(df['date']).apply(lambda date: date.toordinal())

this works, but the problem is that multiple readings taken in the same day are all stacked on the same x-axis point.

Are there better functions than to ordinal to achieve separating readings taken on a same day with decimal values after the day ordinal?

2 Answers

You can calculate the timedeltas between every datetime in the date column and the oldest datetime, then use the timedelta's seconds. This means calculating the relative time (in seconds) since the oldest timestamp:

df['seconds_since_start'] = df['date'].apply(lambda date: (date - df['date'].min()).seconds)

From here, you can convert the seconds to days (with decimal values) using basic math:

df['days_since_start'] = df['seconds_since_start'] / (60 * 60 * 24)

Thanks to @jfaccioni for hinting towards the right direction :) Here's what I did.

First of all to convert a datetime object to a float, so that it could be used by seaborn's scatterplot.

I used the timestamp function which converts a datetime to an epoch (seconds from 01-jan-1970):

df['date_ordinal'] = pd.to_datetime(df['Measurement Date']).apply(lambda date: date.timestamp())

with that I have solved my need. Just to help someone with similar requirements here's a second part.

How to transform back those large seconds numbers back to date strings so they can be used as labels for my seaborn x-axis plot:

# now convert the epoch values back to a YYYY-MM-DD string for the x labels
# localtime converts the epoch into a datetime object abd strftime converts it into a string
new_labels = [time.strftime('%Y-%m-%d',time.localtime(item)) for item in ax.get_xticks()]
ax.set_xticklabels(new_labels)
Related