【问题标题】:Flag if the last element in a group contain particular string in Pandas标记组中的最后一个元素是否包含 Pandas 中的特定字符串
【发布时间】:2019-06-21 21:49:15
【问题描述】:

我有数据:

Group   string
 A     Hello
 A     SearchListing
 A     GoSearch
 A     pen
 A     Hello
 A     Searches
 B     Real-Estate
 B     Access
 B     Denied
 B     Group
 B     Group
 C     Glance
 C     NoSearch
 C     Home
 C     FullSearch

等等。

我想找到那些有一个包含“搜索”作为最后一个元素的字符串的组并标记它们。例如,我想要的输出是这样的:

  Group   Flag
   A       1
   B       0
   C       1

因为 A 和 C 的最后一个元素都包含字符串“search”。 我知道一种可以遍历所有元素的方法,如果最后一个元素包含“搜索”,它将对其进行标记。但它使用循环是一个非常繁重的功能。 有没有更直接的方法?

【问题讨论】:

    标签: python pandas numpy group-by pandas-groupby


    【解决方案1】:

    使用str.contains:

    (df.groupby('Group')['string']
       .last()
       .str.contains('search', case=False)
       .astype(int)
       .rename('Flag')
       .reset_index())
    
      Group  Flag
    0     A     1
    1     B     0
    2     C     1
    

    与上述类似(复制或重置索引以避免SettingWithCopyWarning)。

    u = df.drop_duplicates('Group', keep='last').reset_index(drop=True)
    u['Flag'] = u.pop('string').str.contains('search', case=False).astype(int)
    u
    
      Group  Flag
    0     A     1
    1     B     0
    2     C     1
    

    【讨论】:

      【解决方案2】:

      drop_duplicatescontains 一起使用

      yourdf=df.drop_duplicates('Group',keep='last').\
                 assign(Flag=lambda x : x['string'].str.contains('Search'))
      yourdf
      Out[645]: 
         Group      string   Flag
      5      A    Searches   True
      10     B       Group  False
      14     C  FullSearch   True
      

      【讨论】:

      • 让我再试一次。仔细检查一下。
      • 别在意我的评论,我会删除它。有些案例包含研究。我认为你的工作正常。很抱歉给您带来麻烦。
      【解决方案3】:

      这也有效:

      df.groupby('Group')['string'].apply(lambda x: 'search' in x.str.cat().lower()).reset_index(name='Flag')
      

      输出:

      Group   Flag
      0   A   True
      1   B   False
      2   C   True
      

      速度对比

      %%timeit
      df.drop_duplicates('Group',keep='last').\
                 assign(Flag=lambda x : x['string'].str.contains('Search'))
      # 1000 loops, best of 3: 1.1 ms per loop
      
      %%timeit
      df.groupby("Group")["string"] \
        .apply(lambda x: int("search" in x.values[-1].lower())) \
        .reset_index(name="Flag")
      # 1000 loops, best of 3: 1.6 ms per loop
      
      %timeit df.groupby('Group')['string'].apply(lambda x: 'search' in x.str.cat().lower()).reset_index(name='Flag')
      # 100 loops, best of 3: 1.86 ms per loop
      
      %%timeit
      (df.groupby('Group')['string']
         .last()
         .str.contains('search', case=False)
         .astype(int)
         .rename('Flag')
         .reset_index())
      # 100 loops, best of 3: 2.14 ms per loop
      

      【讨论】:

        【解决方案4】:

        你可以试试:

        df.groupby("Group")["string"] \
          .apply(lambda x: int("search" in x.values[-1].lower())) \
          .reset_index(name="Flag")
        
            Group   Flag
        0   A   1
        1   B   0
        2   C   1
        

        功能方面(根据下面的评论):

        def last_search(df, word):
            return df.groupby("Group")["string"].apply(lambda x: int(word in x.values[-1].lower())).reset_index(name="Flag")
        
        last_search(df, "search")
            Group   Flag
        0   A   1
        1   B   0
        2   C   1
        

        PS

        其他答案也可以这样做

        【讨论】:

        • 另外两种解决方案也有一个衬垫。而且apply很慢,如果可以避免就不推荐了。
        • 知道如何将其放入函数并使用它吗?
        猜你喜欢
        • 2017-02-11
        • 2017-09-28
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 2016-06-17
        • 2019-11-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多