我有一个熊猫数据框,如下所示:
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尤其使我更接近了我想要的东西,尽管它没有找到匹配的前三名。
非常感谢您的帮助或建议。
答案 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']