分组并返回列中存在文本子字符串的所有索引值

Posted

技术标签:

【中文标题】分组并返回列中存在文本子字符串的所有索引值【英文标题】:Group by and return all index values where a substring of text exists in a column 【发布时间】:2022-01-06 18:39:47 【问题描述】:

我有一个结构如下的df

   vid  sid   pid      url 
1   A    A1   page     ABCDEF   
2   A    A1   page     DEF123
3   A    A1   page     GHI345
4   A    A1   page     JKL345
5   B    B1   page     AB12345EF
6   B    B2   page     IJK
7   B    B2   page     XYZ
8   C    C1   page     ABCEF

dict = 'vid':1:'A',2:'A',3:'A',4:'A',5:'B',6:'B',7:'B',8:'C',
        'sid':1:'A1',2:'A1',3:'A1',4:'A1',5:'B1',6:'B2',7:'B2',8:'C1',
        'page':1:'page',2:'page',3:'page',4:'page',5:'page',6:'page',7:'page',8:'pge',
        'url':1:'ABC',2:'DEF',3:'GHI',4:'JKL',5:'ABC',6:'IJK',7:'XYZ',8:'ABC'

我也有一个列表子字符串

lst = ['AB','EF']

基本上,我想按sid 分组并检查url 中的每一行。如果列表中的所有元素作为子字符串存在于至少一行中,则返回sid。如果不存在,则从df 中过滤掉sidurl 中的子字符串不是连续的。

伪代码

group by sid
if row in url contains all the substrings in lst
       pass
if no row in url contains all substrings in lst
       remove the `sid` from the df

使用lst将上述逻辑应用于df的结果

enter code here

      vid  sid   pid      url 
1   A    A1   page     ABCDEF   
2   A    A1   page     DEF123
3   A    A1   page     GHI345
4   A    A1   page     JKL345
5   B    B1   page     AB12345EF
8   C    C1   page     ABCEF

【问题讨论】:

df[df.url.apply(lambda s: any([x in s for x in lst])).groupby(df.sid).transform(any)] 请注意,您共享的字典与表格不同 【参考方案1】:

获取lst中url的布尔掩码:

# `all` check for rows that have both `AB` and `EF`
mask = [all(a in ent for a in lst)  for ent in df.url]
mask = pd.Series(mask, index = df.index)

# Group mask with `Sid` and filter `df`:

df.loc[mask.groupby(df.sid).transform('any')]

  vid sid   pid        url
1   A  A1  page     ABCDEF
2   A  A1  page     DEF123
3   A  A1  page     GHI345
4   A  A1  page     JKL345
5   B  B1  page  AB12345EF
8   C  C1  page      ABCEF

【讨论】:

我正在尝试实现这一点,但我认为它返回的 sids 列表的一个元素存在于 url 列中。我只寻找列表中所有元素至少存在 1 行的 sid。 很好的观察@Sebazz44;更新了代码。看看它是否涵盖了您的用例,或者逻辑中仍然存在泄漏 我实际上是通过将正则表达式管道运算符切换到 AND 等效项来解决它,但是您的解决方案让我足够接近 :) 谢谢!【参考方案2】:

使用布尔索引:

import pandas as pd
gb_df = df.groupby('sid')['url'].transform(lambda x : [x.tolist()]*len(x))
indexing = gb_df.apply(lambda li: any(any(el in text for text in li) for el in lst))

output = df[indexing]

输出:

      vid  sid   pid      url 
1   A    A1   page     ABCDEF   
2   A    A1   page     DEF123
3   A    A1   page     GHI345
4   A    A1   page     JKL345
5   B    B1   page     AB12345EF
8   C    C1   page     ABCEF

【讨论】:

以上是关于分组并返回列中存在文本子字符串的所有索引值的主要内容,如果未能解决你的问题,请参考以下文章

Excel VBA宏获取分号前的文本子字符串

向文本子字符串添加新元素

删除Android小部件中的文本子字符串

Java substring() 方法

Java substring() 方法

如何使用索引标签将 DataFrame 分组并执行操作以根据每个索引在特定列中找到 3 个最大的