对于一般方法: fuzzy_merge
对于更常见的情况,我们要合并包含稍有不同的字符串的两个数据帧中的列,下面的函数difflib.get_close_matches
与一起使用merge
,以便模仿大熊猫的功能,merge
但具有模糊匹配:
import difflib
def fuzzy_merge(df1, df2, left_on, right_on, how='inner', cutoff=0.6):
df_other= df2.copy()
df_other[left_on] = [get_closest_match(x, df1[left_on], cutoff)
for x in df_other[right_on]]
return df1.merge(df_other, on=left_on, how=how)
def get_closest_match(x, other, cutoff):
matches = difflib.get_close_matches(x, other, cutoff=cutoff)
return matches[0] if matches else None
以下是带有两个示例数据帧的一些用例:
print(df1)
key number
0 one 1
1 two 2
2 three 3
3 four 4
4 five 5
print(df2)
key_close letter
0 three c
1 one a
2 too b
3 fours d
4 a very different string e
通过上面的示例,我们将获得:
fuzzy_merge(df1, df2, left_on='key', right_on='key_close')
key number key_close letter
0 one 1 one a
1 two 2 too b
2 three 3 three c
3 four 4 fours d
我们可以通过以下方式进行左联接:
fuzzy_merge(df1, df2, left_on='key', right_on='key_close', how='left')
key number key_close letter
0 one 1 one a
1 two 2 too b
2 three 3 three c
3 four 4 fours d
4 five 5 NaN NaN
对于左连接,我们将在左数据框中将所有不匹配的键设置为None
:
fuzzy_merge(df1, df2, left_on='key', right_on='key_close', how='right')
key number key_close letter
0 one 1.0 one a
1 two 2.0 too b
2 three 3.0 three c
3 four 4.0 fours d
4 None NaN a very different string e
另请注意,如果在截止范围内没有项目匹配,则会返回一个空列表。在共享的示例中,如果我们将最后一个索引更改为:difflib.get_close_matches
df2
print(df2)
letter
one a
too b
three c
fours d
a very different string e
我们会得到一个index out of range
错误:
df2.index.map(lambda x: difflib.get_close_matches(x, df1.index)[0])
IndexError:列表索引超出范围
为了解决这个问题,上面的函数get_closest_match
将difflib.get_close_matches
仅通过索引返回的列表(实际上包含任何匹配项)来返回最接近的匹配项。