как сбросить аналогичные значения в пандах с помощью функции Левенштейна - PullRequest
0 голосов
/ 07 декабря 2018

У меня есть фрейм данных, который выглядит как -

   ML_ENTITY_NAME        EDT_ENTITY_NAME
1  ABC BANK              HABIB METROPOLITAN BANK
2  ABC BANK              HABIB METROPOLITIAN BANK
3  BANK OF AMERICA       HSBC BANK MALAYSIA BHD
4  BANK OF AMERICA       HSBC BANK MALAYSIA SDN BHD
5  BANK OF NEW ZEALAND   HUA NAN COMMERCIAL BANK
6  BANK OF NEW ZEALAND   HUA NAN COMMERCIAL BANK LTD
7  CITIBANK N.A.         CHINA GUANGFA BANK CO LTD
8  CITIBANK N.A.         CHINA GUANGFA BANK CO.,LTD
9  SECURITY BANK CORP.   SECURITY BANK CORP
10 SIAM COMMERCIAL BANK  THE SIAM COMMERCIAL BANK PCL
11 TEMU                  ANZ BANK SAMOA LTD

Я написал функцию Левенштейна, которая выглядит как -

def fm(s1, s2):
    score = Levenshtein.distance(s1,s2)
    if score == 0.0:
        score = 1.0
    else:
        score = 1 - (score / len(s1))
    return score

Я хотел написать код, который, если счет Левенштейнаиз двух EDT_ENTITY_NAME значений равно greater than .75, тогда мы отбрасываем одно значение, имеющее меньшую длину, и сохраняем значение, имеющее большую длину. Также ML_ENTITY_NAME для сравнения должно быть одинаковым.

Мой конечный результат должен выглядеть следующим образом-

   ML_ENTITY_NAME        EDT_ENTITY_NAME
1  ABC BANK              HABIB METROPOLITIAN BANK
2  BANK OF AMERICA       HSBC BANK MALAYSIA SDN BHD
3  BANK OF NEW ZEALAND   HUA NAN COMMERCIAL BANK LTD
4  CITIBANK N.A.         CHINA GUANGFA BANK CO.,LTD
5  SECURITY BANK CORP.   SECURITY BANK CORP
6  SIAM COMMERCIAL BANK  THE SIAM COMMERCIAL BANK PCL
7  TEMU                  ANZ BANK SAMOA LTD

В настоящее время мой подход состоит в том, чтобы отсортировать df и выполнить итерации по циклу и проверить, совпадают ли значения ML_ENTITY_NAME, а затем рассчитать левенштейн для EDT_ENTITY_NAME.я добавил новый столбец удаления и обновляю столбец удаления до 1, если вышеуказанные условия удовлетворяют, а длина ML_ENTITY_NAME меньше, чем у другого ML_ENTITY_NAME.

мой код выглядит как -

df.sort_values(by=['ML_ENTITY_NAME','EDT_ENTITY_NAME'],inplace=True)
df['delete']=0
for row1 in df.itertuples():
    for row2 in df.itertuples():
        if (str(row1.ML_ENTITY_NAME) == str(row2.ML_ENTITY_NAME)) and (1>fm(str(row1.EDT_ENTITY_NAME),str(row2.EDT_ENTITY_NAME))>.74):

            if(len(row1.EDT_ENTITY_NAME)>len(row2.EDT_ENTITY_NAME)):
                df.loc[row2.Index,row2[2]]=1
print(df)

В настоящее время он дает неправильный вывод.

Может кто-нибудь помочь мне с некоторыми ответами / подсказками / предложениями?

Ответы [ 2 ]

0 голосов
/ 07 декабря 2018

Не могли бы вы указать, что именно не так в выводе, который вы получаете?Единственное отклонение от вашей цели, которое я вижу в коде, заключается в том, что вы устанавливаете флаг delete на 1 только для пар строк с 0.74 , тогда как он должен быть скорее 0.75 .

В качестве дополнительного примечания сортировка в вашем коде избыточна, поскольку в конечном итоге вы в любом случае сравниваете каждую возможную пару строк.То, что вы, возможно, имели в виду при реализации сортировки, проходило через каждую последовательную пару строк, что улучшило бы сложность вашего кода с O (n 2 ) до O (n).

Еще одно замечание: вам не нужен оператор if в вашей функции fm: оператор score = 1 - score / len(s1) будет охватывать оба случая.

0 голосов
/ 07 декабря 2018

Я считаю, что вам нужно:

#cross join by ML_ENTITY_NAME column
df1 = df.merge(df, on='ML_ENTITY_NAME', how='outer')
#remove same values per rows (distance 1)
df1 = df1[df1['EDT_ENTITY_NAME_x'] != df1['EDT_ENTITY_NAME_y']]
#apply function and compare
m1 = df1.apply(lambda x: fm(x['EDT_ENTITY_NAME_x'], x['EDT_ENTITY_NAME_y']), axis=1) > .75
m2 = df1['EDT_ENTITY_NAME_x'].str.len() > df1['EDT_ENTITY_NAME_y'].str.len()

#filtering
df2 = df1.loc[m1 & m2, ['ML_ENTITY_NAME','EDT_ENTITY_NAME_x']]
#remove  `_x`
df2.columns = df2.columns.str.replace('_x$', '')
#add unique rows per ML_ENTITY_NAME
df2 = df2.append(df[~df['ML_ENTITY_NAME'].duplicated(keep=False)]).reset_index(drop=True)
print (df2)
         ML_ENTITY_NAME               EDT_ENTITY_NAME
0              ABC BANK      HABIB METROPOLITIAN BANK
1       BANK OF AMERICA    HSBC BANK MALAYSIA SDN BHD
2   BANK OF NEW ZEALAND   HUA NAN COMMERCIAL BANK LTD
3         CITIBANK N.A.    CHINA GUANGFA BANK CO.,LTD
4   SECURITY BANK CORP.            SECURITY BANK CORP
5  SIAM COMMERCIAL BANK  THE SIAM COMMERCIAL BANK PCL
6                  TEMU            ANZ BANK SAMOA LTD
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...