Сгруппируйте и найдите похожие или одинаковые элементы в двух столбцах в Python - PullRequest
1 голос
/ 26 сентября 2019

Для следующего фрейма данных, если строка в name2 приблизительно совпадает или совпадает со строкой в ​​name1 в каждой группе type, тогда возвращается Y, в противном случае N.

   id type     name1      name2
0   1    A  James B.      James
1   2    A     Keras     Steven
2   3    A       NaN      Keras
3   4    B      Jack       Lucy
4   5    B      Lucy       Jack
5   6    C    Jasica     Hoverd
6   7    C    Steven     Jasica
7   8    C       NaN  Steven L.

Ожидаемый результат такой, например, в type A, James из name2 имеют аналогичные значения James B. в name1, Keras имеют те же значенияв обоих name2 и name1, поэтому оба возвращают Y в result.Пока Steven не существует в name1, поэтому верните N.

   id type     name1      name2 result
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

Кто-то может помочь сделать это?Спасибо.

Если найти похожие значения слишком сложно для реализации, найдите только те же значения, и возвращение Y будет в порядке.

Ответы [ 2 ]

2 голосов
/ 26 сентября 2019
df['result'] = pd.DataFrame(df.groupby('type').apply(lambda x: ['Y' if i in ' '.join(x['name1'].astype(str)) else 'N' for i in list(x['name2'].dropna().str.split().str[0])]).tolist()).stack().reset_index(drop=True)

Выход

   id type     name1      name2 result
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
2 голосов
/ 26 сентября 2019

Без сходства это проще:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...