我tf
有一个叫做pandas的数据集,它有一个包含空格分隔关键字的列,标题为"关键字":
Name ... Keywords
0 Jonas 0 ... Archie Betty
1 Jonas 1 ... Archie
2 Jonas 2 ... Chris Betty Archie
3 Jonas 3 ... Betty Chris
4 Jonas 4 ... Daisy
5 Jonas 5 ... NaN
6 Jonas 5 ... Chris Archie
Run Code Online (Sandbox Code Playgroud)
作为输入,我想提供一组字符串来按这些关键字过滤行.我想过使用一个列表:
list = ["Chris", "Betty"]
Run Code Online (Sandbox Code Playgroud)
我发现我可以过滤行,如果我将列表作为一个字符串,其中的条目由"|"分隔:
t="|".join(list)
并在以下列中查找该列中的匹配项:
tf[tf["Keywords"].str.contains(t, na=False)]
这通过查找任何匹配内容进行过滤,因此输出为:
Name ... Keywords
0 Jonas 0 ... Archie Betty
2 Jonas 2 ... Chris Betty Archie
3 Jonas 3 ... Betty Chris
6 Jonas 5 ... Chris Archie
Run Code Online (Sandbox Code Playgroud)
我想要的是:
通过仅包含列表条目和来过滤
通过包含AT LEAST列表条目进行过滤
对于1.结果应该是
3 Jonas 3 ... Betty Chris
对于2.结果应该是:
2 Jonas 2 ... Chris Betty Archie
3 Jonas 3 ... Betty Chris
Run Code Online (Sandbox Code Playgroud)
我发现以下基本上是2的技巧.
a = tf["Keywords"].str.contains("Chris")
b = tf["Keywords"].str.contains("Betty")
tf[a&b]
Run Code Online (Sandbox Code Playgroud)
但是,由于列表长度及其条目可能会有所不同,因此我需要将其设置为通用的.我有一个笨拙的想法,循环交叉每两个连续的列表条目,但这不起作用:
i = 0
while i < len(list)-1:
a = tf["Keywords"].str.contains(list[i])
b = tf["Keywords"].str.contains(list[i+1])
tf = a & b
i += 1
Run Code Online (Sandbox Code Playgroud)
我感谢您的帮助.
注意:
不要使用变量名list
,因为Python代码字。
如果所有关键字只有一个单词且之间没有空格的解决方案:
您可以按空格分割所有单词并将它们转换为set
s,因此可以通过从列表转换而来的集合进行比较L
:
L = ["Chris", "Betty"]
s = set(L)
arr = np.array([set(x.split()) if isinstance(x, str) else set([]) for x in tf["Keywords"]])
print (arr)
[{'Archie', 'Betty'} {'Archie'} {'Chris', 'Archie', 'Betty'}
{'Chris', 'Betty'} {'Daisy'} set() {'Chris', 'Archie'}]
df1 = tf[arr == s]
print (df1)
Name Keywords
3 Jonas 3 Betty Chris
df2 = tf[arr >= s]
print (df2)
Name Keywords
2 Jonas 2 Chris Betty Archie
3 Jonas 3 Betty Chris
Run Code Online (Sandbox Code Playgroud)
处理关键字中多个单词的更通用的解决方案:
print (tf)
Name Keywords
0 Jonas 0 Archie Betty
1 Jonas 1 Archie
2 Jonas 2 Chris Betty Archie
3 Jonas 3 Betty Chris
4 Jonas 4 Daisy Chris Archie Betty
5 Jonas 5 NaN
6 Jonas 5 Chris Archie Betty
L = ["Chris Archie", "Betty"]
s = set(L)
#create pattern with word boundaries
pat = '|'.join(r"\b{}\b".format(x) for x in L)
#extract all keywords and convert to sets
a = tf['Keywords'].str.findall('('+ pat + ')')
a = np.array([set(x) if isinstance(x, list) else set([]) for x in a])
#remove all matched keywords and remove possible traling whitespaces
b = tf['Keywords'].str.replace(pat, '').str.strip()
#compare only matched values and also empty value after replace
df1 = tf[(b == '') & (a == s)]
print (df1)
Name Keywords
6 Jonas 5 Chris Archie Betty
#same like one keyword solution
df2 = tf[a >= s]
print (df2)
Name Keywords
4 Jonas 4 Daisy Chris Archie Betty
6 Jonas 5 Chris Archie Betty
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
132 次 |
最近记录: |