【问题标题】:pandas dataframe search string in the entire row整个行中的熊猫数据框搜索字符串
【发布时间】:2018-06-28 01:48:29
【问题描述】:

我有一个如下所示的熊猫数据框。我想在数据框的每一行中搜索一个文本,并突出显示该文本是否出现在该行中。

例如,我想在每一行中搜索“jones”。我想忽略我的搜索词的大小写。在下面的情况下,我想在名为“jones”的数据中添加一个新列,它的值将是 1,1,0,因为在第一行和第二行中找到了该词

我找到了this 帖子,它显示了如何在列中查找文本,但是当我有很多列时我怎么能找到文本 - 比如 50+?我考虑过连接所有列并创建一个新列,但没有看到任何可以连接数据框所有列的函数(不要求输入每个列名)

我想为我拥有的多个关键字执行此操作。例如,我有关键字列表 LLC, Co, Blue, alpha 和更多 (30+)

sales = [{'account': 'Jones LLC', 'Jan': '150', 'Feb': '200', 'Mar': '140'},
         {'account': 'Alpha Co',  'Jan': 'Jones', 'Feb': '210', 'Mar': '215'},
         {'account': 'Blue Inc',  'Jan': '50',  'Feb': '90',  'Mar': '95' }]
df = pd.DataFrame(sales)

来源 DF:

   Feb    Jan  Mar    account
0  200    150  140  Jones LLC
1  210  Jones  215   Alpha Co
2   90     50   95   Blue Inc

所需的 DF:

   Feb    Jan  Mar    account  jones  llc  co  blue  alpha
0  200    150  140  Jones LLC      1    1   0     0      0
1  210  Jones  215   Alpha Co      1    0   1     0      1
2   90     50   95   Blue Inc      0    0   0     1      0

【问题讨论】:

    标签: pandas dataframe search


    【解决方案1】:

    这里我们使用pandas内置的str函数contains,连同apply,然后把它们和any组合在一起如下,

    search_string = 'Jones'
    
    df[search_string] = (df.apply(lambda x: x.str.contains(search_string))
                           .any(axis=1).astype(int))
    df
    
    Out[2]:
         Feb    Jan    Mar   account     Jones
    0    200    150    140   Jones LLC   1
    1    210    Jones  215   Alpha Co    1
    2    90     50     95    Blue Inc    0
    

    这可以很容易地扩展为contains 使用正则表达式进行匹配。它还有一个大小写参数,以便您可以使其不区分大小写并同时搜索Jonesjones

    为了遍历搜索词列表,我们需要进行以下更改。通过将每个搜索结果(Series)存储在一个列表中,我们使用该列表将系列连接到DataFrame。我们这样做是因为我们不想在新列中搜索新的 search_string,

    df_list = []
    
    for search_string in ['Jones', 'Co', 'Alpha']:
        #use above method but rename the series instead of setting to
        # a columns. The append to a list.
        df_list.append(df.apply(lambda x: x.str.contains(search_string))
                         .any(axis=1)
                         .astype(int)
                         .rename(search_string))
    
    #concatenate the list of series into a DataFrame with the original df
    df = pd.concat([df] + df_list, axis=1)
    df
    
    Out[5]:
        Feb    Jan     Mar    account    Jones  Co   Alpha
    0   200    150     140    Jones LLC  1      0    0
    1   210    Jones   215    Alpha Co   1      1    1
    2   90     50      95     Blue Inc   0      0    0
    

    【讨论】:

    • 如果我有多个搜索字符串,如何一次搜索一个并添加其他列?例如,我想搜索 LLC、Co、Blue、alpha 等,并且我想为每个关键字创建一个新列
    • @Ni_Tempe 这个列表比较小吗?如果是这样,只需重复上述 n 次。否则我认为它是上面那个的for循环......
    • 你处理案件吗?这种方法的问题 9writing for loop for other keywords) 是当我开始搜索第二个关键字时,python 也会搜索最近创建的关键字列......我将有 30 多个关键字
    • @MaxU - 欢迎您保留它 :) 我可以看到这是一个非常简洁的补充!
    • 我发布了一个新问题stackoverflow.com/questions/48346183/…
    【解决方案2】:

    更新:你似乎想要 OneHotEncode 一些特定的词 - 你可以使用 sklearn.feature_extraction.text.CountVectorizer

    In [131]: from sklearn.feature_extraction.text import CountVectorizer
    
    In [132]: vocab = ['jones', 'llc', 'co', 'blue', 'alpha']
    
    In [133]: cv = CountVectorizer(vocabulary=vocab)
    
    In [134]: r = pd.SparseDataFrame((cv.fit_transform(df.select_dtypes('object').add(' ').sum(1)) != 0) * 1,
                                     df.index, 
                                     cv.get_feature_names(), 
                                     default_fill_value=0)
    
    In [135]: r
    Out[135]:
       jones  llc  co  blue  alpha
    0      1    1   0     0      0
    1      1    0   1     0      1
    2      0    0   0     1      0
    

    您也可以将其与您的原始 DF 合并:

    In [137]: df = df.join(r)
    
    In [138]: df
    Out[138]:
       Feb    Jan  Mar    account  jones  llc  co  blue  alpha
    0  200    150  140  Jones LLC      1    1   0     0      0
    1  210  Jones  215   Alpha Co      1    0   1     0      1
    2   90     50   95   Blue Inc      0    0   0     1      0
    

    说明:

    将所有字符串列连接成一个单独的列,使用空格作为分隔符:

    In [165]: df.select_dtypes('object').add(' ').sum(1)
    Out[165]:
    0    200 150 140 Jones LLC LLC
    1       210 Jones 215 Alpha Co
    2            90 50 95 Blue Inc
    dtype: object
    

    生成具有选定特征的 One Hot Encode 稀疏矩阵:

    In [176]: A = (cv.fit_transform(df.select_dtypes('object').add(' ').sum(1)) != 0) * 1
    
    In [177]: A
    Out[177]:
    <3x5 sparse matrix of type '<class 'numpy.int32'>'
            with 6 stored elements in Compressed Sparse Row format>
    
    In [178]: A.A
    Out[178]:
    array([[1, 1, 0, 0, 0],
           [1, 0, 1, 0, 1],
           [0, 0, 0, 1, 0]])
    
    In [179]: cv.get_feature_names()
    Out[179]: ['jones', 'llc', 'co', 'blue', 'alpha']
    

    从中生成一个 SparseDataFrame:

    In [174]: r = pd.SparseDataFrame((cv.fit_transform(df.select_dtypes('object').add(' ').sum(1)) != 0) * 1,
         ...:                        df.index,
         ...:                        cv.get_feature_names(),
         ...:                        default_fill_value=0)
         ...:
         ...:
    
    In [175]: r
    Out[175]:
       jones  llc  co  blue  alpha
    0      1    1   0     0      0
    1      1    0   1     0      1
    2      0    0   0     1      0
    

    【讨论】:

    • 如果我有多个搜索字符串,如何一次搜索一个并添加其他列?例如,我想搜索 LLC、Co、Blue、alpha 等,并且我想为每个关键字创建一个新列
    • @Ni_Tempe 最好将此添加到您的问题中。
    • 我已经有了。这是我问题的最后一行。感谢您的帮助
    • 是的,我现在看到了! - 从评论LLC, Co, Blue, alpha 中添加您的示例可能也值得
    • @Ni_Tempe,请考虑upvoting所有有用的答案和accepting您认为最适合您的答案
    猜你喜欢
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 2018-10-01
    • 1970-01-01
    • 2017-02-24
    • 1970-01-01
    相关资源
    最近更新 更多