在列表中的pandas列中找到关键字匹配项的数量

时间:2018-09-17 20:29:29

标签: python python-3.x pandas nlp nltk

我有一个熊猫数据框,如下所示:

Type        Keywords 
----        --------
Animal      [Pigeon, Bird, Raccoon, Dog, Cat]
Pet         [Dog, Cat, Hamster]
Pest        [Rat, Mouse, Raccoon, Pigeon]
Farm        [Chicken, Horse, Cow, Sheep]
Predator    [Wolf, Fox, Raccoon]

假设我有以下字符串:

input = "There is a dead rat and raccoon in my pool"

鉴于我对字符串进行了标记并删除了停用词,因此它变成了

input = [Dead, Rat, Raccoon, Pool]

我需要遍历每一行并找到关键字匹配次数最多的行。对于给定的示例,结果将如下所示:

Type        Keywords                            Matches
----        --------                            -------
Animal      [Pigeon, Bird, Raccoon, Dog, Cat]   1
Pet         [Dog, Cat, Hamster]                 0
Pest        [Rat, Mouse, Raccoon, Pigeon]       2
Farm        [Chicken, Horse, Cow, Sheep]        0
Predator    [Wolf, Fox, Raccoon]                1

输出将是匹配次数最多的前三个Type名称。

在上述情况下,由于“害虫”类别具有最高的匹配数,因此将其选择为最高匹配项。此外,还将选择“动物”和“捕食者”类别。因此,输出顺序为:

output = [Pest, Animal, Predator]

使用嵌套的for循环执行此任务很容易,但是由于我有成千上万的此类行,因此我正在寻找更好的解决方案。 (另外,由于某些原因,在将非内置函数与pandas一起使用时,我遇到了很多错误,也许是由于矢量化的缘故?)

我查看了熊猫内置的groupby和isin函数,但据我所知,它们将无法使我达到所需的输出(如果我输入错误,我将不会感到惊讶。在这个假设中)。

接下来,我研究了熊猫使用集合和哈希图的情况,但是不幸的是,我的编码知识和当前能力还不足以熟练地制定可靠的解决方案。 This StackOverflow link尤其使我更接近了我想要的东西,尽管它没有找到匹配的前三名。

非常感谢您的帮助或建议。

2 个答案:

答案 0 :(得分:3)

您可以选中isin

df['Matches']=pd.DataFrame(df.Keywords.values.tolist()).isin(s).sum(1)


df.loc[df['Matches']>0,'Type'].values.tolist()

答案 1 :(得分:2)

在DataFrame中的列表上存储和操作不是很有效,也就是说,我们可以在此处使用set相交:

设置

s = set(['Dead', 'Rat', 'Raccoon', 'Pool'])

现在使用列表推导(比apply更快):

out = df.assign(Matches=[len(set(el) & s) for el in df.Keywords])

<!- ->

       Type                           Keywords  Matches
0    Animal  [Pigeon, Bird, Raccoon, Dog, Cat]        1
1       Pet                [Dog, Cat, Hamster]        0
2      Pest      [Rat, Mouse, Raccoon, Pigeon]        2
3      Farm       [Chicken, Horse, Cow, Sheep]        0
4  Predator               [Wolf, Fox, Raccoon]        1

要查找匹配度最高的三行:

out.loc[out.Matches.nlargest(3).index].Type.tolist()

['Pest', 'Animal', 'Predator']