【问题标题】:Searching Multiple Strings in pandas without predefining number of strings to use在 pandas 中搜索多个字符串而不预先定义要使用的字符串数
【发布时间】:2019-06-06 18:33:44
【问题描述】:

我想知道是否有更通用的方法来执行以下操作?我想知道是否有一种方法可以创建 st 函数,以便我可以搜索非预定义数量的字符串?

例如,能够创建一个通用的 st 函数,然后键入 st('Governor', 'Virginia', 'Google)

这是我当前的函数,但它预定义了两个可以使用的词。 (df 是一个熊猫数据框)

def search(word1, word2, word3 df):
    """
    allows you to search an intersection of three terms
    """
    return df[df.Name.str.contains(word1) & df.Name.str.contains(word2) & df.Name.str.contains(word3)]

st('Governor', 'Virginia', newauthdf)

【问题讨论】:

    标签: python pandas


    【解决方案1】:

    你可以使用np.logical_and.reduce:

    import pandas as pd
    import numpy as np
    def search(df, *words):  #1
        """
        Return a sub-DataFrame of those rows whose Name column match all the words.
        """
        return df[np.logical_and.reduce([df['Name'].str.contains(word) for word in words])]   # 2
    
    
    df = pd.DataFrame({'Name':['Virginia Google Governor',
                               'Governor Virginia',
                               'Governor Virginia Google']})
    print(search(df, 'Governor', 'Virginia', 'Google'))
    

    打印

                           Name
    0  Virginia Google Governor
    2  Governor Virginia Google
    

    1. def search(df, *words) 中的* 允许search 接受一个 无限数量的位置参数。它将收集所有 参数(在第一个之后)并将它们放在一个名为 words 的列表中。
    2. np.logical_and.reduce([X,Y,Z]) 等价于 X & Y & Z。它 但是,允许您处理任意长的列表。

    【讨论】:

    • 抱歉,'OR' 是否有等价物?如果我还想混入 or 和 and 搜索,我该怎么做?
    • 有两种处理OR的方法。您可以将正则表达式模式与 | 结合起来,如 behzad.nouri 所示,或者您可以使用 np.logical_or.reduce。然而,允许用户输入正则表达式(可能包含|)并使用search 将正则表达式与np.logical_and.reduce 组合起来可能是最简单的。
    【解决方案2】:

    str.contains 可以使用正则表达式。所以你可以使用'|'.join(words)作为模式;为了安全起见,也映射到re.escape

    >>> df
                     Name
    0                Test
    1            Virginia
    2              Google
    3  Google in Virginia
    4               Apple
    
    [5 rows x 1 columns]
    >>> words = ['Governor', 'Virginia', 'Google']
    

    '|'.join(map(re.escape, words)) 将是搜索模式:

    >>> import re
    >>> pat = '|'.join(map(re.escape, words))
    >>> df.Name.str.contains(pat)
    0    False
    1     True
    2     True
    3     True
    4    False
    Name: Name, dtype: bool
    

    【讨论】:

    • 这很有帮助!我喜欢这两个答案,但我选择了下面的一个,因为它允许您输入一个任意长的带有 *words 的答案列表,这是我不知道的。我也不知道 regex 在 str.contains 中工作,所以这非常有用。
    • 是否可以在不使用 and 运算符的情况下在多个字段上运行 contains?伪:'df['Name', 'AnotherField'].str.contains(pattern)
    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 2021-09-05
    • 1970-01-01
    • 2012-10-15
    • 2018-01-13
    • 2017-09-09
    • 1970-01-01
    相关资源
    最近更新 更多