Сходство между двумя столбцами данных - PullRequest
0 голосов
/ 28 мая 2018

У меня есть два кадра данных, и у каждого есть столбец с именем Song.Однако иногда песни пишутся по-разному.Как я могу использовать difflib (или что-то подобное), чтобы получить правописание песни одного кадра данных в новом столбце другого кадра данных?

ex:

Dataframe1

Song           Artist

like a virgi   madonna


Dataframe2

Song          Rank

like a virgin  2


Result

Song            Artist    SongAlt

like a virgin   Madonna   like a virgi

1 Ответ

0 голосов
/ 28 мая 2018

Шаг 1: объединить все, что можно объединить

In [67]: df1
Out[67]: 
           Song    Artist
0        mysong  myartist
1  like a virgi   madonna

In [68]: df2
Out[68]: 
            Song  Rank
0         mysong     1
1  like a virgin     2

In [69]: merged = pd.merge(df1, df2, on='Song')

In [70]: merged
Out[70]: 
     Song    Artist  Rank
0  mysong  myartist     1

Шаг 2: выяснить, что осталось

In [71]: unmerged = df2[~df2.isin(merged)].dropna()

In [72]: unmerged
Out[72]: 
            Song  Rank
1  like a virgin   2.0

Шаг 3: Используйте difflib get_close_matches, чтобы получить наиболее близкое совпадение

In [73]: songs = list(df1['Song'].unique())

In [74]: def closest(a):
    ...:     try:
    ...:         return difflib.get_close_matches(a, songs)[0]
    ...:     except IndexError:
    ...:         return "Not Found"

In [75]: unmerged['closest_song'] = unmerged.apply(lambda row: closest(row['Song']), axis=1)

In [76]: unmerged
Out[76]: 
            Song  Rank  closest_song
1  like a virgin   2.0  like a virgi

Шаг 4: Получите процент сходства, если хотите

In [77]: def similar(a, b):
    ...:     return difflib.SequenceMatcher(None, a, b).ratio()

In [78]: unmerged['Similarity'] = unmerged.apply(lambda row: similar(row['closest_song'], row['Song']), axis=1)

In [79]: unmerged
Out[79]: 
            Song  Rank  closest_song  Similarity
1  like a virgin   2.0  like a virgi        0.96

Шаг 5: объединить с использованием ближайших значений

In [80]: unmerged.rename(columns={'Song': 'Old_Song', 'closest_song': 'Song'}, inplace=True)

In [81]: new = unmerged.merge(df1, on='Song')[['Song', 'Artist', 'Rank']]
Out[81]: 
           Song   Artist  Rank
0  like a virgi  madonna   2.0

In [82]: pd.concat([merged, new])
Out[82]: 
           Song    Artist  Rank
0        mysong  myartist   1.0
0  like a virgi   madonna   2.0
...