In any case, to get a column that is indexed the same as the original dataframe (as is being tried in the OP), the canonical way is to transform the function using groupby.transform
(as suggested by @DSM in a comment). The sorting has to be done beforehand.
df['new'] = df.sort_values(by='L3', ascending=False).groupby('L1')['L3'].transform(lambda y: y.cumsum()/y.sum())
Yet another way is to perform the division outside the groupby
ditching lambda
altogether.
g = df.sort_values(by='L3', ascending=False).groupby('L1')['L3']df['new'] = g.cumsum() / g.transform('sum')