Вы можете попробовать это:
(df.bfill() + df.fillna(' (copy)').where(df.isna())).fillna(df)
Или
df.bfill().add(df.fillna(' (copy)').where(df.isna(), ''))
Вывод:
column1 column2 column3 column4
0 a cat mouse cheese
1 b dog (copy) NaN food (copy)
2 c dog NaN food