How do I convert a column to dates and extract the month or year in pandas?
Short answer
Convert the column with to_datetime, then read parts through the dt accessor such as dt.year or dt.month. Set the format or dayfirst argument when parsing is ambiguous.
The short version
Turn text into real dates with pd.to_datetime, then pull out parts through the .dt accessor, for example dt.year, dt.month or dt.day_name(). Until you convert, a date column is just strings, and sorting or filtering on it will behave alphabetically rather than chronologically.
A worked example
import pandas as pd
df = pd.DataFrame({"d": ["2021-03-01", "2021-12-25"]})
df["d"] = pd.to_datetime(df["d"])
print(df["d"].dt.month.tolist()) # [3, 12]
print(df["d"].dt.day_name().tolist()) # ['Monday', 'Saturday']
Once converted, the whole .dt family is available: dt.year, dt.month, dt.day, dt.dayofweek, dt.quarter, dt.hour, and so on.
Why conversion matters first
If the column stays as text, "2021-12-25" < "2021-03-01" compares character by character, so December can sort before March. After to_datetime, comparisons and sorting are chronological, and date arithmetic works.
The ambiguity trap
The string 03/04/2021 could be the 3rd of April or the 4th of March. Pandas cannot know which, so state your intent.
pd.to_datetime("03/04/2021", dayfirst=True) # 3rd of April
pd.to_datetime("03/04/2021", format="%d/%m/%Y")
Passing an explicit format is the most reliable choice, and it is also faster on large columns because pandas does not have to guess.
Handling bad values
Real data contains entries that will not parse. Use errors="coerce" to turn those into NaT, the datetime version of a missing value, rather than raising.
pd.to_datetime(["2021-01-01", "not a date"], errors="coerce")
You can then count or drop the NaT rows with isna, just as with numeric NaN.
Grouping by a date part
A common follow-on task is summarising by month or year. Extract the part, then group.
df.groupby(df["d"].dt.year).size()