如何合并具有合并索引字符串差异的多个数据集?
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
匹配项。这有助于减少手动数据清理工作,尽管这通常是不可避免的,至少在某种程度上是这样。
希望对您有所帮助。
您好,我正在努力寻找可能是一个非常普遍的问题的解决方案。
我想将两个 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
匹配项。这有助于减少手动数据清理工作,尽管这通常是不可避免的,至少在某种程度上是这样。
希望对您有所帮助。