Resampling
What You Will Learn in This Lesson
By the end of this lesson, you will be able to:
- Bucket rows into time periods.
- Say why a period with no rows still appears.
- Pick the right frequency string.
- Explain why that matters for a chart.
Why This Matters
A group-by on a month key omits months with no data. Plotted, that gap becomes a straight line between two points that were never adjacent, and the chart shows a trend that did not happen. resample produces every period in the range, so a quiet month is visible as a zero rather than invisible.
Step 1: resample is group-by for time
With a datetime index, resample buckets rows into periods — monthly, weekly, daily — and then you name the summary, exactly as with a group-by.
The call
A frequency string and a summary. "MS" is month start, "W" weekly, "D" daily, "YE" year end.
import pandas as pd
idx = pd.to_datetime(["2024-01-05", "2024-01-20", "2024-02-01"])
s = pd.Series([1, 2, 5], index=idx)
print(s.resample("MS").sum())
Any summary, not just sum
Mean, max, count — whatever you would ask a group for.
import pandas as pd
idx = pd.to_datetime(["2024-01-05", "2024-01-20", "2024-02-01"])
s = pd.Series([1, 2, 5], index=idx)
print(s.resample("MS").agg(["sum", "mean", "size"]))
Mini Practice #1: Monthly and weekly
Try It YourselfResample this series by month and then by week, and compare how many buckets each gives.
Step 2: Empty periods appear
Unlike a group-by, resample produces every period in the range, including the ones with no rows.
The quiet month
January and March have data; February does not. resample reports it as 0; a group-by would leave it out entirely.
import pandas as pd
idx = pd.to_datetime(["2024-01-01", "2024-03-01"])
s = pd.Series([1, 1], index=idx)
print(s.resample("MS").sum())
print(s.groupby(s.index.month).sum())
Two points on a chart from the group-by, three from the resample. The two-point version draws a line straight through a month that had nothing in it.
Zero is not always the honest fill
For a count, an empty period really is zero. For a mean it is unknown, and sum() quietly turning it into 0 would claim a month averaged nothing.
import pandas as pd
idx = pd.to_datetime(["2024-01-01", "2024-03-01"])
s = pd.Series([10.0, 30.0], index=idx)
print(s.resample("MS").sum()) # February reads 0
print(s.resample("MS").mean()) # February reads NaN, which is true
Mini Practice #2: The missing month
Try It YourselfCompare the resample with the group-by and count the buckets each produces.
Step 3: When to Use It
Totals per period
Daily rows to weekly or monthly totals without building a period column.
df["sales"].resample("MS").sum()
Finding gaps
resample includes periods with no rows, so size() shows where data is missing.
When Not to Use It
Do not read a zero in a resampled sum as “nothing happened”. An empty period also sums to zero — check size() to tell them apart.
End-of-Lesson Exercises
Exercise 1: Monthly totals, gaps included
Write monthly_totals(s) that takes a Series indexed by date and returns a list of monthly totals, including months with nothing in them.
resample("MS") buckets by month start. The quiet month in the middle is the whole point: a group-by would skip it and the timeline would lie.
Exercise 2: How many periods were empty
Write quiet_months(s) returning how many months in the range had no rows at all. Use a summary where an empty period is distinguishable from a period that summed to zero.
resample("MS").size() gives the row count per period, and the empty ones are the zeros. Using sum() instead would confuse a quiet month with one whose values happened to cancel out.