【问题标题】:How to compare a list of similar strings in python for sport games?如何比较体育游戏中python中相似字符串的列表?
【发布时间】:2020-07-15 14:08:18
【问题描述】:

我有一个包含各种属性的体育游戏词典列表。这些列表都是由列表中的一项运动组成的。所以我有一个篮球比赛列表,棒球比赛列表等等。

我想以相同的方式格式化所有“游戏”值,例如,相同的特定体育比赛(Pit Steelers vs LA Rams)都具有相同的字符串值。特定游戏的示例可以是"PIT Steelers vs LA Rams",但也可以格式化为"Pittsburgh Steelers vs Los Angeles Rams"。对于特定游戏,我的列表中最多可能有 7 个字典,格式略有不同。

我不能选择只使用球队名称或城市,因为在同一项运动中,可能会在 NFL 和 NCAA 等两个不同联赛中与那些特定球队名称或城市进行相同的比赛。

我想我会使用最广泛的游戏名称作为关键。例如,我将使用"Pittsburgh Steelers vs Los Angeles Rams" 而不是"PIT Steelers vs LA Rams" 作为用作基线的键。

有没有办法我可以将这些其他匹配项与密钥进行比较,并说如果密钥中此字符串的百分比超过 X,则用密钥替换此字符串游戏?你会怎么做?我愿意接受所有建议!

谢谢!

编辑:这是使用 difflib 的尝试。我生成了 1000 个随机游戏并导入到 excel 中并按比例排序。我们可以看到它并不完美。

【问题讨论】:

  • 您可以尝试拆分“vs”部分并应用 Levenshtein 距离。但它似乎不是很健壮。我认为最好的方法是拥有一本包含所有可能变体的字典:teams = {"PIT Steelers": ["PIT Steelers", "Pittsburgh Steelers"], "other team": ["variant1", "variant2"]}
  • 这取决于你如何定义相似。例如,“螃蟹”与“废话”相似吗?
  • 因为我是从第三方网站上抓取这些内容,让我拥有一本包含所有可能变体的所有运动的字典几乎是不可能的。
  • 我会说,如果在关键的扩展变体中发现了 75% 左右的较小变体字符,我可能会很有信心地说它们是匹配的。
  • 这不是一个容易解决的问题 - 您可以尝试为一个团队累积一个包含所有别名的表,将这些别名指向一个选定的键,然后通过别名查找一个团队。桌子的建造要么需要人工干预,要么需要一些复杂的机械......您可以尝试使用您指出的 75% 匹配来缩短复杂性,也许效果很好,很难说。

标签: python string string-comparison


【解决方案1】:

创建一个不包括城市的短队名称列表,然后扫描标题以查找这些短名称。您应该在每个标题中找到两个简短的团队名称,然后您可以使用它们将标题分组到独特的游戏中。

team_long_names = ['Arizona Cardinals', 'Atlanta Falcons', 'Carolina Panthers', 'Chicago Bears',
         'Dallas Cowboys', 'Detriot Lions','Green Bay Packers','Los Angeles Rams',
         'Minnesota Vikings','New Orleans Saints','New York Giants', 'Philadelphia Eagles',
         'San Francisco 49ers','Seattle Seahawks','Washington Redskins','Baltimore Ravens',
         'Buffalo Bills','Cinncinnati Bangals','Cleveland Browns','Denver Broncos',
         'Houston Texans','Indanapolis Colts','Jacksonville Jaguars','Kansas City Chiefs',
         'Las Vegas Raiders','Los Angeles Chargers','Miami Dolphins','New England Patriots',
         'New York Jets','Pittsburgh Steelers','Tennessee Titans']

team_short_names = [n.lower().split(' ')[-1] for n in team_long_names]

game_titles = ['Atlanta Falcons vs New York Jets', 'ATL Falcons vs NY Jets', 'Falcons v Jets',
            'SF 49ers vs PIT Steelers', 'San Fransico 49ers vs Pittsburg Steelers', '49ers vs Steelers',
            'Dallas Cowboys vs LA Chargers', 'DAL Cowboys vs Los Angles Chargers', 'Cowboys v Chargers',
            'Blah blah Falcons and Foo bar Jets']

titles_by_key = []

for title in game_titles:
    game_key = '-'.join([word for word in title.lower().split(' ') if word in team_short_names])
    titles_by_key.append(game_key + ": " + title)

print(sorted(titles_by_key))

输出:

['49ers-steelers: 49ers vs Steelers',
 '49ers-steelers: SF 49ers vs PIT Steelers',
 '49ers-steelers: San Fransico 49ers vs Pittsburg Steelers',
 'cowboys-chargers: Cowboys v Chargers',
 'cowboys-chargers: DAL Cowboys vs Los Angles Chargers',
 'cowboys-chargers: Dallas Cowboys vs LA Chargers',
 'falcons-jets: ATL Falcons vs NY Jets',
 'falcons-jets: Atlanta Falcons vs New York Jets',
 'falcons-jets: Blah blah Falcons and Foo bar Jets',
 'falcons-jets: Falcons v Jets']

这并不能解决可能与不同联赛的球队名称冲突的问题,但我怀疑可能有更简单的策略来检测联赛作为预处理步骤。

【讨论】:

  • 我认为你是对的。我尝试了一堆不同的 difflib 策略,但如果你可以将它分成联赛,那么你可以只使用球队名称,你可以确定没有误报。
  • 但即便如此,我也确信有同名的 NCAA 球队。我很好奇聚合网站如何处理这个问题。
  • 我不认为这是一个完美的解决方案,但我同意你为已知的不太可能改变的联赛处理它的方式。我将在这里为所有不太可能更改团队名称的联赛(例如主要职业运动)使用您的理由。然后我可能会使用 difflib 和 if 语句来尝试找出不同运动的匹配项。
【解决方案2】:

您可以使用fuzzy wuzzy 库来替换字符串。制作团队的主要列表,然后您可以使用fuzzy wuzzy 包提取与其他字符串最相似的团队。但它并不完美,因为您需要测试不同的场景,例如'CAR' 不会返回Carolina Panthers,它会返回'Arizona Cardinals',而'LVR' 会返回'Los Angels Rams' .所以你只需要付费,然后可能对于这少数情况,只需制定一些逻辑来找回合适的团队。

from fuzzywuzzy import process

nfl_teams = ['Arizona Cardinals', 'Atlanta Falcons', 'Carolina Panthers', 'Chicago Bears',
         'Dallas Cowboys', 'Detriot Lions','Green Bay Packers','Los Angeles Rams',
         'Minnesota Vikings','New Orleans Saints','New York Giants', 'Philadelphia Eagles',
         'San Francisco 49ers','Seattle Seahawks','Washington Redskins','Baltimore Ravens',
         'Buffalo Bills','Cinncinnati Bangals','Cleveland Browns','Denver Broncos',
         'Houston Texans','Indanapolis Colts','Jacksonville Jaguars','Kansas City Chiefs',
         'Las Vegas Raiders','Los Angeles Chargers','Miami Dolphins','New England Patriots',
         'New York Jets','Pittsburgh Steelers','Tennessee Titans']

matchups = ['OAK Raiders vs CHI Bears','GB Packers vs MIN Vikings','PIT Steelers vs LA Rams', 'PHI vs DEN']
for each in matchups:
    team1, team2 = each.split('vs')[0].strip(), each.split('vs')[-1].strip()
    team1_alpha = process.extractOne(team1, nfl_teams)[0]
    team2_alpha = process.extractOne(team2, nfl_teams)[0]
    
    print ('%s ----->   %s vs %s' %(each, team1_alpha, team2_alpha))

输出:

OAK Raiders vs CHI Bears ----->   Las Vegas Raiders vs Chicago Bears
GB Packers vs MIN Vikings ----->   Green Bay Packers vs Minnesota Vikings
PIT Steelers vs LA Rams ----->   Pittsburgh Steelers vs Los Angeles Rams
PHI vs DEN ----->   Philadelphia Eagles vs Denver Broncos

或者,如果您确实想进行比较以查看它们的相似程度。

from fuzzywuzzy import fuzz
var1 = "Pittsburgh Steelers vs Los Angeles Rams" 
var2 = "PIT Steelers vs LA Rams"

print(fuzz.ratio(var1, var2))  

print(fuzz.token_sort_ratio(var1, var2))

print(fuzz.token_set_ratio(var1, var2))

输出:

68
71
82

【讨论】:

  • fuzzy wuzzy vs difflib 有什么好处?
  • 我从未使用过 difflib,但看起来它本质上是一样的。我看到了你的结果。如果您在 'vs' 上拆分并以这种方式重建可能会有所帮助。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-25
  • 1970-01-01
  • 2010-10-31
  • 2010-10-19
  • 1970-01-01
  • 2015-06-24
  • 2023-03-31
相关资源
最近更新 更多