Option 1
Vectorized rsplitwith understanding
from numpy.core.defchararray import rsplit
v = df.string.values.astype(str)
s = df.s.values.astype(str)
df.assign(string=[' '.join([x.strip() for x in y]) for y in rsplit(v, s, 1)])
string s
0 the best new york cheesecake ny new york
1 houston public school houston
2
re.sub
s, .
import re
v = df.string.values.astype(str)
s = df.s.values.astype(str)
f = lambda i, j: re.sub(r' *{0} *(?!.*{0}.*)'.format(i), ' ', j).strip()
df.assign(string=[f(i, j) for i, j in zip(s, v)])
string s
0 the best new york cheesecake ny new york
1 houston public school houston