
本文介绍如何使用 Pandas 库,基于两个数据表中姓名列的部分字符串匹配,实现模糊合并。针对姓名存在简称、别名等情况,通过 str.contains 方法进行高效匹配,避免使用模糊字符串匹配算法带来的性能瓶颈和不准确性,从而完成数据表的连接。
基于部分字符串匹配合并数据表
当需要合并两个包含姓名信息的数据表,但姓名格式不完全一致时(例如,一个表使用全名,另一个表使用简称或别名),传统的精确匹配方法将失效。一种有效的解决方案是利用 Pandas 的 str.contains 函数进行部分字符串匹配,实现模糊合并。
步骤 1:准备数据
假设我们有两个 Pandas DataFrame:df1 和 df2。df1 包含 'short_name' 列,df2 包含 'long_name' 列。我们需要基于这两个姓名列进行合并。
步骤 2:使用 str.contains 进行匹配
我们可以使用 str.contains 函数来检查 df2['long_name'] 是否包含 df1['short_name'] 中的字符串。 为了获得更准确的结果,我们需要对 df1 的每一行进行迭代,并对 df2 进行过滤。
import pandas as pd
# 示例数据
data1 = {'short_name': ['Tammy Abraham', 'Mason Mount', 'Christian Pulisic']}
df1 = pd.DataFrame(data1)
data2 = {'long_name': ['Kevin Oghenetega Tamaraebi Bakumo-Abraham', 'Mason Tony Mount', 'Christian Mate Pulisic']}
df2 = pd.DataFrame(data2)
def merge_partial_name(df1, df2, short_name_col, long_name_col):
"""
基于部分姓名匹配合并两个 DataFrame。
Args:
df1: 包含简称/别名的数据表。
df2: 包含全名的数据表。
short_name_col: df1 中简称/别名所在的列名。
long_name_col: df2 中全名所在的列名。
Returns:
合并后的 DataFrame。
"""
merged_df = pd.DataFrame()
for index, row in df1.iterrows():
short_name = row[short_name_col]
# 使用 str.contains 查找匹配的行
matched_rows = df2[df2[long_name_col].str.contains(short_name, na=False)]
# 如果找到匹配项,则将 df1 的行与 df2 的匹配行合并
if not matched_rows.empty:
# 这里假设只匹配到一行,如果匹配到多行,需要根据实际情况处理
merged_row = pd.concat([row, matched_rows.iloc[0]])
merged_df = pd.concat([merged_df, merged_row.to_frame().T], ignore_index=True)
return merged_df
# 调用函数进行合并
merged_df = merge_partial_name(df1, df2, 'short_name', 'long_name')
print(merged_df)代码解释:
- merge_partial_name(df1, df2, short_name_col, long_name_col) 函数: 定义了一个函数,接收两个 DataFrame 和姓名列名作为输入。
- 循环遍历 df1: 使用 df1.iterrows() 遍历 df1 的每一行。
- str.contains(short_name, na=False): 使用 str.contains 函数,查找 df2[long_name_col] 中包含 short_name 的行。na=False 用于处理缺失值,防止因为缺失值导致匹配失败。
- 合并匹配的行: 如果找到匹配的行(not matched_rows.empty),则将 df1 的当前行与 df2 的匹配行使用 pd.concat 进行合并。 由于str.contains可能匹配到多行,这里假设只匹配到一行,使用matched_rows.iloc[0]选取第一行进行合并。如果匹配到多行,需要根据实际情况选择合适的匹配行。
- pd.concat([merged_df, merged_row.to_frame().T], ignore_index=True): 将合并后的行添加到结果 DataFrame merged_df 中。 merged_row.to_frame().T 将Series转置为DataFrame,ignore_index=True 重新设置索引。
步骤 3:处理匹配结果
上述代码仅仅是一个基本示例。在实际应用中,可能需要处理以下情况:
- 多个匹配项: str.contains 可能会找到多个匹配项。你需要根据实际情况选择最佳匹配项。例如,可以根据其他列的信息进行筛选,或者使用更复杂的字符串匹配算法(如编辑距离)来选择最相似的匹配项。
- 没有匹配项: 可能存在 df1 中的姓名在 df2 中找不到匹配项的情况。你需要决定如何处理这些未匹配的行。可以选择保留这些行,并将 df2 中的列填充为缺失值,或者直接删除这些行。
- 性能优化: 如果数据量很大,循环遍历 DataFrame 可能会比较慢。可以考虑使用向量化操作来提高性能。例如,可以使用 apply 函数结合 str.contains 来实现向量化匹配。
注意事项:
- str.contains 默认进行大小写敏感的匹配。如果需要进行大小写不敏感的匹配,可以使用 case=False 参数。
- str.contains 使用正则表达式进行匹配。如果 short_name 中包含正则表达式的特殊字符,需要进行转义。
- 在处理大量数据时,建议对代码进行性能测试,并根据实际情况进行优化。
总结:
通过使用 Pandas 的 str.contains 函数,可以方便地实现基于部分字符串匹配的数据表合并。这种方法在处理姓名格式不一致的数据时非常有效。在实际应用中,需要根据具体情况处理多个匹配项、没有匹配项以及性能优化等问题。










