Вы можете разделить большой фрейм данных на куски, скажем, по 200 тыс. Строк.
n = 200000 #chunk row size
list_df = [df2[i:i+n] for i in range(0, df2.shape[0],n)]
Затем объедините все фрагментированные df с df1:
res = pd.DataFrame()
for chunk in list_df:
res = pd.concat([res, df1.merge(chunk, how='left', left_on=['x','y'], right_on['x','y'])