I think you can use merge_ordered :
#first convert columns to datetime df1.Quarter_End = pd.to_datetime(df1.Quarter_End) df2.Date = pd.to_datetime(df2.Date) df = pd.merge_ordered(df1, df2, left_on=['Company','Quarter_End'], right_on=['Company','Date'], how='outer') print (df) Company Period Quarter_End Date Price 0 M 2016Q1 2015-05-02 NaT NaN 1 M NaN NaT 2015-06-20 1.05 2 M NaN NaT 2015-06-22 4.05 3 M NaN NaT 2015-07-10 3.45 4 M NaN NaT 2015-07-29 1.86 5 M 2016Q2 2015-08-01 NaT NaN 6 M NaN NaT 2015-08-24 1.58 7 M NaN NaT 2015-09-02 8.64 8 M NaN NaT 2015-09-22 2.56 9 M NaN NaT 2015-10-20 5.42 10 M 2016Q3 2015-10-31 NaT NaN 11 M NaN NaT 2015-11-02 1.58 12 M NaN NaT 2015-11-24 4.58 13 M NaN NaT 2015-12-03 6.48 14 M NaN NaT 2015-12-05 4.56 15 M NaN NaT 2016-01-03 7.14 16 M 2016Q4 2016-01-30 2016-01-30 6.34 17 WFM 2015Q2 2015-04-12 NaT NaN 18 WFM NaN NaT 2015-06-20 1.05 19 WFM NaN NaT 2015-06-22 4.05 20 WFM 2015Q3 2015-07-05 NaT NaN 21 WFM NaN NaT 2015-07-10 3.45 22 WFM NaN NaT 2015-07-29 1.86 23 WFM NaN NaT 2015-08-24 1.58 24 WFM NaN NaT 2015-09-02 8.64 25 WFM NaN NaT 2015-09-22 2.56 26 WFM 2015Q4 2015-09-27 NaT NaN 27 WFM NaN NaT 2015-10-20 5.42 28 WFM NaN NaT 2015-11-02 1.58 29 WFM NaN NaT 2015-11-24 4.58 30 WFM NaN NaT 2015-12-03 6.48 31 WFM NaN NaT 2015-12-05 4.56 32 WFM NaN NaT 2016-01-03 7.14 33 WFM 2016Q1 2016-01-17 2016-01-17 6.34
Then fill in the NaN in the Period and Quarter_End bfill and aggregate sum . If you want to remove all NaN values, add Series.dropna and the last reset_index :
df.Period = df.Period.bfill() df.Quarter_End = df.Quarter_End.bfill() print (df.groupby(['Company','Period','Quarter_End'])['Price'].sum().dropna().reset_index()) Company Period Quarter_End Price 0 M 2016Q2 2015-08-01 10.41 1 M 2016Q3 2015-10-31 18.20 2 M 2016Q4 2016-01-30 30.68 3 WFM 2015Q3 2015-07-05 5.10 4 WFM 2015Q4 2015-09-27 18.09 5 WFM 2016Q1 2016-01-17 36.10
source share