【问题标题】:How do I fuzzy match items in a column of an array in python?如何模糊匹配python中数组列中的项目?
【发布时间】:2016-12-22 23:25:53
【问题描述】:

我有一组来自 NCAA 的球队名称,以及与之相关的统计数据。学校名称通常会缩短或完全省略,但名称的所有变体通常都有一个共同的元素(例如 Alabama Crimson Tide vs Crimson Tide)。这些名称都包含在一个数组中,没有特定的顺序。我希望能够通过模糊匹配来获取团队名称的所有变体并将所有变体重命名为一个名称。我在 python 2.7 中工作,我有一个包含所有数据的 numpy 数组。任何帮助将不胜感激,因为我以前从未使用过模糊匹配。

我考虑过通过 for 循环进行模糊匹配,它会(尽管速度慢得令人难以置信)将数组列中的每个元素与其他每个元素进行比较,但我不确定如何构建它。

目前,我的数组如下所示:

{姓名 , info1, info2, info 3}

数组有几千行长,所以我试图让程序尽可能高效。

【问题讨论】:

  • 在内存中的数组上运行的 for 循环中,几千行应该很快。
  • 在我最后一次尝试这样做时,它从未完成。我确实同意它不应该永远持续下去,所以我一定做错了什么。我只是不确定如何解决这个循环。

标签: python-2.7 fuzzy-comparison


【解决方案1】:

Levenshtein edit distance 是执行字符串模糊匹配的最常用方法。它在python-Levenshtein package 中可用。另一个流行的距离是Jaro Winkler's distance,也可以在同一个包中使用。

假设一个简单的数组numpy数组:

import numpy as np
import Levenshtein as lv

ar = np.array([
      'string'
    , 'stum'
    , 'Such'
    , 'Say'
    , 'nay'
    , 'powder'
    , 'hiden'
    , 'parrot'
    , 'ming'
    ])

我们定义帮助器来为我们提供 Levenshtein 和 Jaro 距离的索引,在我们拥有的字符串和数组中的所有字符串之间。

def levenshtein(dist, string):
    return map(lambda x: x<dist, map(lambda x: lv.distance(string, x), ar))

def jaro(dist, string):
    return map(lambda x: x<dist, map(lambda x: lv.jaro_winkler(string, x), ar))

现在,请注意,Levenshtein 距离是一个以字符数计算的整数值,而 Jaro 的距离是一个浮点值,通常在 0 和 1 之间变化。让我们使用 np.where 进行测试:

print ar[np.where(levenshtein(3, 'str'))]
print ar[np.where(levenshtein(5, 'str'))]
print ar[np.where(jaro(0.00000001, 'str'))]
print ar[np.where(jaro(0.9, 'str'))]

我们得到:

['stum']
['string' 'stum' 'Such' 'Say' 'nay' 'ming']
['Such' 'Say' 'nay' 'powder' 'hiden' 'ming']
['string' 'stum' 'Such' 'Say' 'nay' 'powder' 'hiden' 'parrot' 'ming']

【讨论】:

  • 太棒了,谢谢!我一直在尝试安装 python-Levenshtein 包,我没有意识到我需要一个 c++ 编译器才能安装它,但这确实有助于解决我的问题
  • @a7xcarter - 嗯,你想要速度,所以基于 C 的实现是最快的。但是,也许,我应该提一下jellyfish,它完全用python编写,还导出.levenshtein_distance.jaro_distance
猜你喜欢
  • 2022-12-24
  • 1970-01-01
  • 1970-01-01
  • 2020-11-01
  • 2014-07-14
  • 1970-01-01
  • 2019-12-28
  • 2019-04-05
  • 1970-01-01
相关资源
最近更新 更多