Без сходства это проще:
mask = df.groupby('type', group_keys=False).apply(lambda x: x['name2'].isin(x['name1']))
df['new'] = np.where(mask, 'Y','N')
print (df)
id type name1 name2 new
0 1 A James B. James N
1 2 A Keras Steven N
2 3 A NaN Keras Y
3 4 B Jack Lucy Y
4 5 B Lucy Jack Y
5 6 C Jasica Hoverd N
6 7 C Steven Jasica Y
7 8 C NaN Steven L. N
С базовым сходством с разделением:
mask = (df.assign(name1 = df['name1'].fillna('|').astype(str).str.split().str[0],
name2 = df['name2'].astype(str).str.split().str[0])
.groupby('type', group_keys=False)
.apply(lambda x: x['name2'].isin(x['name1'])))
df['new'] = np.where(mask, 'Y','N')
print (df)
id type name1 name2 new
0 1 A James B. James Y
1 2 A Keras Steven N
2 3 A NaN Keras Y
3 4 B Jack Lucy Y
4 5 B Lucy Jack Y
5 6 C Jasica Hoverd N
6 7 C Steven Jasica Y
7 8 C NaN Steven L. Y
Для лучшего совпадения возможно подобие, используйте SequenceMatcher
для отношения и фильтруйте его по порогуНапример, здесь 0.5
:
from difflib import SequenceMatcher
def f(x):
comp = [any(SequenceMatcher(None, a, b).ratio() > .5
for a in x['name1'].fillna('_'))
for b in x['name2']]
return pd.Series(comp, index=x.index)
mask = df.groupby('type', group_keys=False).apply(f)
df['new'] = np.where(mask, 'Y','N')
print (df)
id type name1 name2 new
0 1 A James B. James Y
1 2 A Keras Steven N
2 3 A NaN Keras Y
3 4 B Jack Lucy Y
4 5 B Lucy Jack Y
5 6 C Jasica Hoverd N
6 7 C Steven LA. Jasica Y
7 8 C NaN Steven L. Y