在 Pandas 中模糊搜索列

Posted

技术标签:

【中文标题】在 Pandas 中模糊搜索列【英文标题】:Fuzzy Searching a Column in Pandas 【发布时间】:2021-01-16 09:50:12 【问题描述】:

有没有办法使用FuzzyWuzzy 或类似库在数据框列中搜索值? 我试图在一个列中找到一个与另一列中的值相对应的值,同时考虑到模糊匹配。所以

例如,如果我在一列中有 州名,而在另一列中有 州代码,我将如何找到佛罗里达州的州代码,即 FL 同时提供餐饮服务像“Flor”这样的缩写?

也就是说,我想找到与“Flor”对应的州名的匹配项,并获得相应的州代码“FL”。

非常感谢任何帮助。

【问题讨论】:

【参考方案1】:

如果缩写都是前缀,您可以使用.startswith() 字符串方法来处理状态的短版本或长版本。

>>> test_value = "Flor"
>>> test_value.upper().startswith("FL")
True
>>> "Florida".lower().startswith(test_value.lower())
True

但是,如果您有更复杂的缩写,difflib.get_close_matches 可能会满足您的需求!

>>> import pandas as pd
>>> import difflib
>>> df = pd.DataFrame("states": ("Florida", "Texas"), "st": ("FL", "TX"))
>>> df
    states  st
0  Florida  FL
1    Texas  TX
>>> difflib.get_close_matches("Flor", df["states"].to_list())
['Florida']
>>> difflib.get_close_matches("x", df["states"].to_list(), cutoff=0.2)
['Texas']
>>> df["st"][df.index[df["states"]=="Texas"]].iloc[0]
'TX'

您可能想尝试/排除IndexError 从 difflib 读取返回列表的第一个成员,并可能调整截止以减少与关闭状态的错误匹配(也许提供所有状态作为 可能性 给某些用户或需要更多字母来表示关闭状态)。

您还可能会看到将两者结合起来的最佳结果;在尝试模糊匹配之前先测试前缀。

把它们放在一起

def state_from_partial(test_text, df, col_fullnames, col_shortnames):
    if len(test_text) < 2:
        raise ValueError("must have at least 2 characters")

    # if there's exactly two characters, try to directly match short name
    if len(test_text) == 2 and test_text.upper() in df[col_shortnames]:
        return test_text.upper()

    states = df[col_fullnames].to_list()
    match = None
    # this will definitely fail at least for states starting with M or New
    #for state in states:
    #    if state.lower().startswith(test_text.lower())
    #        match = state
    #        break  # leave loop and prepare to find the prefix

    if not match:
        try:  # see if there's a fuzzy match
            match = difflib.get_close_matches(test_text, states)[0]  # cutoff=0.6
        except IndexError:
            pass  # consider matching against a list of problematic states with different cutoff

    if match:
        return df[col_shortnames][df.index[df[col_fullnames]==match]].iloc[0]

    raise ValueError("couldn't find a state matching partial: ".format(test_text))

注意以“New”或“M”(可能还有其他)开头的状态,它们都非常接近并且可能需要特殊处理。测试将在这里创造奇迹。

【讨论】:

以上是关于在 Pandas 中模糊搜索列的主要内容,如果未能解决你的问题,请参考以下文章

关于Lucene怎么使用SpanQuery进行模糊搜索

C# combobox 模糊搜索。

mysql怎么实现全局的模糊搜索?

ES实现模糊搜索

input 模糊搜索

Mongodb数据库的模糊搜索