如何合并具有合并索引字符串差异的多个数据集?

how to merge multiple datasets with differences in merge-index strings?

您好,我正在努力寻找可能是一个非常普遍的问题的解决方案。

我想将两个 csv 文件与足球数据合并。它们基本上存储相同游戏的不同数据。通常我会用 .merge 进行合并,但问题是,两个数据集中的某些团队的命名法不同。因此,例如 Manchester City 在第二个数据帧中被称为 Man. City

df1 和 df2 大致如下所示:

df:

team1            team2     date                      some_value_i_want_to_compare
Manchester City  Arsenal   2022-05-20 22:00:00 0.2812  5

df2:

team1       team2     date                      some_value_i_want_to_compare
Man. City   Arsenal   2022-05-20 22:00:00 0.2812  3

请注意,在上述情况下,只有 team1 存在差异,但也可能存在 team2 略有不同的情况。因此,例如在这种情况下,Arsenal 可以在第二个数据集中被称为 FC Arsenal

所以我的主要问题是:如何自动分析两个数据集命名的差异?

我的第二个问题是:如何针对 2 个以上的数据集进行缩放,以便数据集的数量最终无关紧要?

您可以先执行 anti-join 以隔离不匹配的那些:

# Merge two team datasets
teams_join = df1.merge(df2, on='team1', 
                                 how='left', indicator=True)

# Select the team1 column where _merge is left_only
team_list = teams_join.loc[teams_join['_merge'] == 'left_only', 'team1']

# print team names in df1 with no match in df2
print(df1[df1["team1"].isin(team_list)])

这将为您提供 df1 中没有 df2 比赛的所有球队。您可以对 df2 执行相同的操作(只需反转前面代码中的所有 df1 和 df2)。然后,您可以获取名称不匹配的这两个列表,如果它们足够少,则手动重命名它们。

正如评论者和现有答案所建议的那样,如果唯一名称的数量不是太多,那么您可以手动提取不匹配项并进行更正。这可能是最好的解决方案,除非不匹配的数量非常大。

另一种可能发生的情况是,当您有一个允许索引的基本事实列表(例如,给定联赛中所有足球队的列表)时,但数据可能包含许多不同的拼写或缩写尝试每个组。如果这与您的情况相似,您可以使用 difflib 搜索给定名称的最可能匹配项。例如:

import difflib

true_names = ['Manchester United', 'Chelsea']
mismatch_names = ['Man. Unites', 'Chlsea', 'Chelsee']
best_matches = [difflib.get_close_matches(x, true_names, n=1) for x in mismatch_names]
for old,new in zip(mismatch_names, best_matches):
    print(f"Best match for {old} is {new[0]}")

输出:

Best match for Man. Unites is Manchester United
Best match for Chlsea is Chelsea
Best match for Chelsee is Chelsea

请注意,如果拼写非常糟糕,您可以要求 difflib 使用 n= 关键字参数找到最接近的 n 匹配项。这有助于减少手动数据清理工作,尽管这通常是不可避免的,至少在某种程度上是这样。

希望对您有所帮助。