You can (and should) use pd.PeriodIndex
as a first step, then convert to timestamp using PeriodIndex.to_timestamp
:
qs = df['Quarter'].str.replace(r'(Q\d) (\d+)', r'\2-\1')
qs
0 1996-Q3
1 1996-Q4
2 1997-Q1
Name: Quarter, dtype: object
df['date'] = pd.PeriodIndex(qs, freq='Q').to_timestamp()
df
Quarter date
0 Q3 1996 1996-07-01
1 Q4 1996 1996-10-01
2 Q1 1997 1997-01-01
The initial replace step is necessary as PeriodIndex
expects your periods in the %Y-%q
format.
Another option is to use pd.to_datetime
after performing string replacement in the same way as before.
df['date'] = pd.to_datetime(
df['Quarter'].str.replace(r'(Q\d) (\d+)', r'\2-\1'), errors="coerce")
df
Quarter date
0 Q3 1996 1996-07-01
1 Q4 1996 1996-10-01
2 Q1 1997 1997-01-01
If performance is important, you can split and join, but you can do it cleanly:
df['date'] = pd.to_datetime([
'-'.join(x.split()[::-1]) for x in df['Quarter']])
df
Quarter date
0 Q3 1996 1996-07-01
1 Q4 1996 1996-10-01
2 Q1 1997 1997-01-01