A Datetime Index
What You Will Learn in This Lesson
By the end of this lesson, you will be able to:
- Move a date column onto the index.
- Select a period with a string.
- Say why the index must be sorted.
- Get the column back when you need it.
Why This Matters
A DatetimeIndex is what makes the rest of this unit possible: partial-string selection, resampling and rolling windows all read the index. It is also the one place in pandas where an unsorted index gives you a wrong answer rather than an error.
Step 1: set_index on a date column
With time on the index, a string is enough to select a period.
Partial string selection
The string names a period rather than an instant. "2024" is a year, "2024-01" is a month.
import pandas as pd
df = pd.DataFrame({
"day": pd.to_datetime(["2024-01-05", "2024-01-20", "2024-02-01"]),
"n": [1, 2, 5],
}).set_index("day")
print(df.loc["2024-01"])
print(df.loc["2024-01"]["n"].sum())
A range between two dates
A slice on a DatetimeIndex includes both ends, like every other loc slice.
import pandas as pd
df = pd.DataFrame({
"day": pd.to_datetime(["2024-01-05", "2024-01-20", "2024-02-01"]),
"n": [1, 2, 5],
}).set_index("day")
print(df.loc["2024-01-05":"2024-01-20"])
Mini Practice #1: Select a month
Try It YourselfPut the day on the index and print just January, then just its total.
Step 2: Order matters
Slicing a time index expects it sorted. Sorting once after setting it is the habit worth keeping.
Sort it and forget about it
A file is often already in date order, and often not. One call removes the question.
import pandas as pd
df = pd.DataFrame({
"day": pd.to_datetime(["2024-02-01", "2024-01-05"]),
"n": [5, 1],
}).set_index("day").sort_index()
print(df)
print(df.index.is_monotonic_increasing)
And getting the column back
reset_index() is the way out, for when you want a plain table again — to write to a file, or to join.
import pandas as pd
df = pd.DataFrame({"day": pd.to_datetime(["2024-01-05"]), "n": [1]}).set_index("day")
print(list(df.reset_index().columns))
Mini Practice #2: Sort before slicing
Try It YourselfSet the index on this out-of-order table, sort it, and confirm the index is now increasing.
Step 3: When to Use It
A series measured over time
With dates on the index, df.loc["2024-03"] selects a whole month.
df = df.set_index("date").sort_index()
Before resampling or rolling
Both need time on the index to know how far apart the rows are.
When Not to Use It
Do not slice a date index that is not sorted. Partial-string selection on an unsorted index can raise or return the wrong rows.
End-of-Lesson Exercises
Exercise 1: The total in a month
Write month_total(df, month) where df has a datetime day column and a numeric n, and month is a string like "2024-01". Return the total of n in that month.
Set the day as the index and sort it, then select the month string. An empty selection sums to 0, which is the answer the first hidden case wants.
Exercise 2: The span the data covers
Write date_span(df) that puts the day column on a sorted index and returns a two-element list of [first date, last date] as YYYY-MM-DD strings. Reporting the span is part of describing any time series.
set_index("day").sort_index(), then the first and last index entries. strftime("%Y-%m-%d") turns each back into a plain string.