繁体   English   中英

即使关键字存在于数据框中,Pandas isin() 也不返回任何内容

[英]Pandas isin() does not return anything even when the keywords exist in the dataframe

我想在文本列中搜索关键字列表并选择存在确切关键字的所有行。 我知道这个问题有很多重复,但我不明白为什么该解决方案不适用于我的情况。

keywords = ['fake', 'false', 'lie']

df1:

文本
19152 我认为她是冠状病毒……
19154 男孩,你讨厌看到那个。 我的意思是看看它是如何被收容的。
19155 告诉她这只是假流感,过几天就会消失。
19235 这是假新闻吗?
... ...
20540 她会相信这只是替代事实。

预期结果:我想在我的列表中选择具有确切关键字的行('fake'、'false'、'lie)。 例如,在上面的 df 中,它应该返回第 19155 和 19235 行。

str.contains()

df1[df1['text'].str.contains("|".join(keywords))]

str.contains()的问题在于结果不限于确切的关键字。 例如,它返回带有believe的句子(例如,第20540 行),因为lie是“believe”的子串!

熊猫系列.isin

为了找到包含确切关键字的行,我使用了 pd.Series.isin

df1[df1.text.isin(keywords)]
#df1[df1['text'].isin(keywords)]

即使我看到 df1 中有匹配项,它也不会返回任何内容。 有人可以帮我吗? 谢谢!

更新:

@Lazyer 和 @BeRT2me 提供的答案都是正确的。 我接受了@lazyer 的回答,因为他发布得更快。 但是,我更喜欢@@BeRT2me 的答案,因为它简短而简单:)

import re

df[df.text.apply(lambda x: any(i for i in re.findall('\w+', x) if i in keywords))]

输出:

                                                text
2  Tell her it’s just the fake flu, it will go aw...
3                                 Is this fake news?

如果文字如下,

df1 = pd.DataFrame()
df1['text'] = [
    "Dear Kellyanne, Please seek the help of Paula White I believe ...",
    "trump saying it was under controll was a lie, ...",
    "Her mouth should hanve been ... All the lies she has told ...",
    "she'll believe ...",
    "I do believe in ...",
    "This value is false ...",
    "This value is fake ...",
    "This song is fakelove ..."
]
keywords = ['misleading', 'fake', 'false', 'lie']

第一的,

简单的方法是这样的。

df1[df1.text.apply(lambda x: True if pd.Series(x.split()).isin(keywords).sum() else False)]
                      text
5  This value is false ...
6   This value is fake ...

它不会捕捉到“相信”这样的词,但因为特殊的字母而无法捕捉到“谎言”等词。

第二,

因此,如果删除文本数据中的特殊字母,例如

new_text = df1.text.apply(lambda x: re.sub("[^0-9a-zA-Z]+", " ", x))
df1[new_text.apply(lambda x: True if pd.Series(x.split()).isin(keywords).sum() else False)]

现在它可以捕捉到“谎言”这个词。

                                                text
1  trump saying it was under controll was a lie, ...
5                            This value is false ...
6                             This value is fake ...

第三,

它仍然无法捕捉到谎言这个词。 它可以通过使用一个库来解决,该库将不同形式的动词标记为相同的动词。 你可以从这里找到如何标记( tokenize-words-in-a-list-of-sentences-python

我认为拆分单词然后匹配是一种更好更直接的方法,例如,如果dfkeywords

df = pd.DataFrame({'text': ['lama abc', 'cow def', 'foo bar', 'spam egg']})
keywords = ['foo', 'lama']

df

       text
0  lama abc
1   cow def
2   foo bar
3  spam egg

这应该返回正确的结果

df.loc[pd.Series(any(word in keywords for word in words) for words in df['text'].str.findall(r'\w+'))]

       text
0  lama abc
2   foo bar

解释

首先,在df['text']中进行单词拆分

splits = df['text'].str.findall(r'\w+')

splits

0    [lama, abc]
1     [cow, def]
2     [foo, bar]
3    [spam, egg]
Name: text, dtype: object

然后我们需要查找是否存在连续的任何单词应该出现在关键字中

# this is answer for a single row, if words is the split list of that row
any(word in keywords for word in words)

# for the entire dataframe, use a Series, `splits` from above is word split lists for every line
rows = pd.Series(any(word in keywords for word in words) for words in splits)
rows

0     True
1    False
2     True
3    False
dtype: bool

现在我们可以找到正确的行

df.loc[rows]

       text
0  lama abc
2   foo bar

请注意,这种方法可能会消耗更多内存,因为它需要在每一行上生成拆分列表。 因此,如果您拥有庞大的数据集,这可能是个问题。

我相信这是因为pd.Series.isin()检查字符串是否在列中,而不是列中的字符串是否包含特定单词。 我刚刚测试了这个代码片段:

s = pd.Series(['lama abc', 'cow', 'lama', 'beetle', 'lama',
               'hippo'], name='animal')

s.isin(['cow', 'lama'])

正如我所想的那样,第一个字符串,即使包含单词“lama”,也会返回 False。

也许尝试使用正则表达式? 看到这个: 在pandas dataframe python列中搜索一个词

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM