Group by 和 return 列中存在文本子字符串的所有索引值
Group by and return all index values where a substring of text exists in a column
我有一个具有以下结构的 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
中的每一行。如果列表中的所有元素在至少一行中作为子字符串存在,则 return 为 sid
。如果不存在,则从 df 中过滤掉 sid
。 url
中的子串不是连续的。
伪代码
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
使用布尔索引:
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
获取 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
我有一个具有以下结构的 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
中的每一行。如果列表中的所有元素在至少一行中作为子字符串存在,则 return 为 sid
。如果不存在,则从 df 中过滤掉 sid
。 url
中的子串不是连续的。
伪代码
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
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
使用布尔索引:
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
获取 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