join
и reindex
d = d2.set_index(['A', 'C'])
d = d.reindex(pd.MultiIndex.from_product(d.index.levels, names=d.index.names))
d.join(d1.set_index('A')).reset_index().sort_index(1)
A B C D
0 a z 1 xy
1 a z 2 xv
2 b y 1 xc
3 b y 2 NaN
4 c x 1 NaN
5 c x 2 xb
Переставить некоторые вещи, чтобы точно соответствовать OP
d = d2.set_index(['C', 'A'])
d = d.reindex(pd.MultiIndex.from_product(d.index.levels, names=d.index.names))
d.join(d1.set_index('A')).sort_index().reset_index().sort_index(1)
A B C D
0 a z 1 xy
1 b y 1 xc
2 c x 1 NaN
3 a z 2 xv
4 b y 2 NaN
5 c x 2 xb
Умное использование pd.concat
pd.concat(d.merge(d1.assign(C=i), 'outer') for i, d in d2.groupby('C'))
A B C D
0 a z 1 xy
1 b y 1 xc
4 c x 1 NaN
2 a z 2 xv
5 b y 2 NaN
3 c x 2 xb