We've all grown up studying groupy by and aggregations in SQL. Pandas provides excellent functionality for group by and aggregations. However, for time series data, we need a bit of manipulation. In this post, I'll take a small example of weather time series data.

import pandas as pd
import matplotlib.pyplot as plt
plt.style.use('ggplot')
%matplotlib inline
df = pd.read_csv("weather.csv", index_col=0, parse_dates=True).tz_localize("UTC").tz_convert("US/Central")
df.head()
humidity temperature
2015-01-01 00:00:00-06:00 0.73 38.74
2015-01-01 01:00:00-06:00 0.74 38.56
2015-01-01 02:00:00-06:00 0.75 38.56
2015-01-01 03:00:00-06:00 0.79 37.97
2015-01-01 04:00:00-06:00 0.80 37.78

Question 1: What is the mean temperature and humidity per hour of the day?

We'll create a new column in the df containing the hour information from the index.

df["hour"] = df.index.hour
df.head()
humidity temperature hour
2015-01-01 00:00:00-06:00 0.73 38.74 0
2015-01-01 01:00:00-06:00 0.74 38.56 1
2015-01-01 02:00:00-06:00 0.75 38.56 2
2015-01-01 03:00:00-06:00 0.79 37.97 3
2015-01-01 04:00:00-06:00 0.80 37.78 4
mean_temp_humidity = df.groupby("hour").mean()
mean_temp_humidity.head()
humidity temperature
hour
0 0.779322 45.976441
1 0.803898 44.859492
2 0.812203 44.244407
3 0.819153 43.724068
4 0.832712 43.105763
mean_temp_humidity.plot(subplots=True);

We can use pivoting to achieve the same dataframe.

mean_temp_humidity_pivoting = pd.pivot_table(df, index=["hour"], values=["temperature", "humidity"])
mean_temp_humidity_pivoting.head()
humidity temperature
hour
0 0.779322 45.976441
1 0.803898 44.859492
2 0.812203 44.244407
3 0.819153 43.724068
4 0.832712 43.105763

By default the aggregation function used in pivoting is mean.

Question 2: Can we plot the daily variation in temperature per hour of the day?

For this, we want to have a dataframe with hour of day as the index and the different days as the different columns.

df["day"] = df.index.dayofyear
df.head()
humidity temperature hour day
2015-01-01 00:00:00-06:00 0.73 38.74 0 1
2015-01-01 01:00:00-06:00 0.74 38.56 1 1
2015-01-01 02:00:00-06:00 0.75 38.56 2 1
2015-01-01 03:00:00-06:00 0.79 37.97 3 1
2015-01-01 04:00:00-06:00 0.80 37.78 4 1
daily_temp = pd.pivot_table(df, index=["hour"], columns=["day"], values=["temperature"])
daily_temp.head()
temperature
day 1 2 3 4 5 6 7 8 9 10 ... 50 51 52 53 54 55 56 57 58 59
hour
0 38.74 39.94 39.57 41.83 33.95 36.98 46.93 29.95 36.57 36.19 ... 46.17 54.01 66.57 55.49 37.68 30.34 34.97 39.93 36.19 32.25
1 38.56 39.76 39.75 40.85 32.29 35.89 45.33 28.55 37.31 36.40 ... 41.38 54.56 66.57 55.49 36.76 30.04 34.97 36.37 36.38 32.25
2 38.56 39.58 39.94 39.73 31.59 36.44 44.51 27.44 37.78 36.59 ... 39.99 55.81 66.57 55.34 35.56 30.57 34.75 34.74 36.20 32.25
3 37.97 38.83 40.16 38.78 30.48 36.85 43.92 25.97 37.97 36.38 ... 39.05 57.14 66.38 55.27 34.94 30.59 35.15 34.31 36.20 32.52
4 37.78 39.02 40.65 39.74 29.89 35.72 44.37 24.74 37.82 35.49 ... 37.99 57.51 66.57 55.49 34.04 30.38 35.15 33.02 34.49 32.52

5 rows × 59 columns

daily_temp.plot(style='k-', alpha=0.3, legend=False)
plt.ylabel("Temp");

So, we can see some pattern up there! Around 15 hours, the temperature usually peaks.

There you go! Some recipes for aggregation and plotting of time series data.