Вы можете применять drop_duplicates построчно:
df.apply(lambda x: x.drop_duplicates(), axis=1)
Column_1 Column_2 Column_3
0 A B NaN
1 D C NaN
2 E NaN NaN
3 F G H
РЕДАКТИРОВАТЬ:
Основываясь на предложении DeepSpace, я сделал несколько моментов времени, чтобы посмотреть, будет ли применение pd.Series.drop_duplicates быстрее.чем использование лямбды.
df = pd.DataFrame({'Column_1':np.random.randint(1,10,10**4),
'Column_2':np.random.randint(1,10,10**4),
'Column_3':np.random.randint(1,10,10**4)})
%timeit df.apply(lambda x: x.drop_duplicates(), axis=1)
435 ms ± 8.24 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
%timeit df.apply(pd.Series.drop_duplicates, axis=1)
443 ms ± 15.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
К сожалению, оба решения работают довольно медленно (1000 строк уже занимают полсекунды).