При работе с большими наборами данных в Pandas часто необходимо сопоставлять строки в разных столбцах или фреймах данных. В этой статье мы обсудим несколько методов сопоставления строк в Pandas, включая точное сопоставление, приблизительное сопоставление с помощью fuzzywuzzy и приблизительное сопоставление с расстоянием Левенштейна.

Точное соответствие

Чтобы выполнить точное сопоставление в Pandas, вы можете использовать функцию merge() для объединения двух фреймов данных в определенном столбце, а затем использовать полученный фрейм данных для поиска строк, в которых значения в двух столбцах совпадают. Вот пример:

import pandas as pd
# Create DataFrame1
data1 = {'column_A': ['apple', 'banana', 'orange', 'pineapple']}
df1 = pd.DataFrame(data1)
# Create DataFrame2
data2 = {'column_B': ['orange', 'kiwi', 'mango', 'banana']}
df2 = pd.DataFrame(data2)
# Use merge() function to join on column_A and column_B
result = pd.merge(df1, df2, left_on='column_A', right_on='column_B')
# Find matches
matches = result[result['column_A'] == result['column_B']]

Приблизительное соответствие с Fuzzywuzzy

Чтобы выполнить приблизительное сопоставление в Pandas, вы можете использовать библиотеку fuzzywuzzy. Эта библиотека предоставляет несколько алгоритмов сопоставления строк, включая token_sort_ratio, token_set_ratio и partial_ratio. Вот пример того, как вы можете использовать алгоритм token_sort_ratio для поиска приблизительных совпадений между двумя столбцами column_A и column_B в двух кадрах данных df1 и df2:

from fuzzywuzzy import fuzz
import pandas as pd

# Create DataFrame1
data1 = {'column_A': ['apple', 'banana', 'orange', 'pineapple']}
df1 = pd.DataFrame(data1)

# Create DataFrame2
data2 = {'column_B': ['orange', 'kiwi', 'mango', 'banana']}
df2 = pd.DataFrame(data2)

# Create an empty list to store the match scores
scores = []

# Iterate through the rows of both DataFrames
for index1, row1 in df1.iterrows():
    for index2, row2 in df2.iterrows():
        # Calculate the match score using fuzz.token_sort_ratio
        score = fuzz.token_sort_ratio(row1['column_A'], row2['column_B'])
        scores.append({'index1': index1, 'index2': index2, 'score': score})

# Create a new DataFrame from the scores list
scores_df = pd.DataFrame(scores)

# Find the matches where score is greater than some threshold (e.g. 80)
threshold = 80
matches = scores_df[scores_df['score'] >= threshold]

Приближенное согласование с расстоянием Левенштейна

Расстояние Левенштейна — это еще один способ измерения сходства между двумя строками, известное как «расстояние редактирования», поскольку оно вычисляет минимальное количество односимвольных правок (вставок, удалений или замен), необходимых для преобразования одной строки в другую. Вот пример использования функции Levenshtein.distance() из пакета Левенштейна:

import Levenshtein
import pandas as pd

# Create DataFrame1
data1 = {'column_A': ['apple', 'banana', 'orange', 'pineapple']}
df1 = pd.DataFrame(data1)

# Create DataFrame2
data2 = {'column_B': ['orange', 'kiwi', 'mango', 'banana']}
df2 = pd.DataFrame(data2)

# Create an empty list to store the match scores
scores = []

# Iterate through the rows of both DataFrames
for index1, row1 in df1.iterrows():
    for index2, row2 in df2.iterrows():
        # Calculate the match score using Levenshtein.distance
        score = Levenshtein.distance(row1['column_A'], row2['column_B'])
        scores.append({'index1': index1, 'index2': index2, 'score': score})

# Create a new DataFrame from the scores list
scores_df = pd.DataFrame(scores)

# Find the matches where score is lower than some threshold (e.g. 2)
threshold = 2
matches = scores_df[scores_df['score'] <= threshold]

Важно иметь в виду, что при использовании расстояния Левенштейна следует использовать меньший порог для сопоставления, так как функция возвращает количество операций редактирования (удалений, вставок и замен), необходимых для превращения одной строки в другую, и меньшее число означает большее сходство. В этом посте мы обсудили несколько методов сопоставления строк в Pandas, включая точное сопоставление, приблизительное сопоставление с помощью fuzzywuzzy и приблизительное сопоставление с расстоянием Левенштейна. Каждый метод имеет свои преимущества и недостатки, и выбор того, какой из них использовать, зависит от конкретного варианта использования и размера набора данных, с которым вы работаете.

Примеры использования пакета Левенштейна в сравнении с Fuzzywuzzy

Пакет Левенштейна использует реализацию алгоритма расстояния Левенштейна, который, как известно, является относительно быстрым для вычисления расстояния редактирования между двумя строками. Функция Levenshtein.distance() реализована на C, поэтому обычно она работает быстрее, чем реализация алгоритма расстояния Левенштейна на чистом Python.

Пакет Fuzzywuzzy, с другой стороны, использует различные алгоритмы, такие как token_sort_ratio, token_set_ratio или partial_ratio, для поиска сходства строк, у этих алгоритмов есть свои компромиссы в производительности. Например, алгоритм token_sort_ratio относительно быстр и не имеет больших накладных расходов, в то время как другие алгоритмы, такие как token_set_ratio, имеют больше накладных расходов и требуют больше времени для расчета.

С точки зрения чистой производительности пакет Левенштейна, вероятно, быстрее, чем fuzzywuzzy, особенно если вы работаете с большими наборами данных. Однако fuzzywuzzy обеспечивает большую гибкость и удобство за счет реализации нескольких алгоритмов сопоставления строк, поэтому он будет более полезен в сценариях, когда точное совпадение не ожидается, а вы хотите найти приблизительные совпадения.

Как правило, это зависит от конкретного варианта использования и размера вашего набора данных. Если вы работаете с небольшими наборами данных и вам не нужна гибкость, обеспечиваемая fuzzywuzzy, то пакет Левенштейна может быть лучшим выбором. Однако, если вы работаете с большими наборами данных и вам нужна гибкость, обеспечиваемая fuzzywuzzy, то это может быть лучшим выбором.