【发布时间】:2020-07-09 15:05:01
【问题描述】:
我正在参加 Kaggle COVID-19 比赛 (https://www.kaggle.com/allen-institute-for-ai/CORD-19-research-challenge/tasks),只是想看看我能不能提供帮助。我有一个关于提高 Pandas DataFrame 中正则表达式搜索效率的问题。
我已经组织了数据集,因此我的数据框在每一行中都有标题、摘要和文章的全文。目标是使用正则表达式在全文中搜索关键字,然后在新列中返回一个集合。作为第一步,我正在搜索每篇文章中提到的病毒。我还使用国际病毒分类委员会的数据集来帮助我识别病毒 (https://talk.ictvonline.org/files/master-species-lists/m/msl/8266)
虽然我知道我的数据集很大,并且“全文”列中有很多数据(400,000 多行,全文列中有 100 多个单词),但我当前的脚本运行已运行 2日不停。我想看看是否有办法提高它的效率,因为我想运行其他正则表达式搜索,最好不用等那么久。
我创建了一个模拟数据集,但使用的是我正在使用的脚本。有什么办法让我提高它的效率吗?
import pandas as pd
import re
模拟数据集
df = pd.DataFrame(data = {"Title": ["Article 1", "Article 2", "Article 3"],
"Abstract":["Abstract 1", "Abstract 2", "Abstract 3"],
"Text":["Lorem ipsum dolor sit amet, consectetur adipiscing elit, coronavirus sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, papavirus, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia paleovirus deserunt mollit anim id est laborum.",
"Lorem ipsum dolor sit amet, paleovirus consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui coronavirus officia deserunt mollit anim id est laborum.",
"Lorem coronavirus ipsum dolor sit amet, astrovirus consectetur adipiscing elit, sed do eiusmod tempor astrovirus incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."]
})
这是来自ICTV网站,我从网站下载了电子表格,要复制,请下载电子表格,并更改文件夹路径
virus = pd.read_excel(r"D:\Python work\2020-03-13\ICTV Master Species List 2018b.v2.xlsx", sheet_name = "ICTV 2018b Master Species #34 v")
组织数据
virus = virus[['Realm', 'Subrealm', 'Kingdom', 'Subkingdom', 'Phylum',
'Subphylum', 'Class', 'Subclass', 'Order', 'Suborder', 'Family',
'Subfamily', 'Genus', 'Subgenus', 'Species']]
我已将数据集合并为一列。文章可能会以不同的形式提及相同的病毒(冠状病毒、冠状病毒科、冠状病毒科等。我想捕获所有版本)
virus = virus.melt(id_vars= None, var_name = "virus_class", value_name = "virus_name")
virus.drop_duplicates(subset = ["virus_name"], inplace=True)
virus.dropna(subset = ["virus_name"], inplace=True)
virus["virus_name"] = virus["virus_name"] .apply(lambda x : x.lower())
据我了解,所有的病毒名称都会有词干“vir”,可以在开头、中间或结尾。
这些行尝试使用正则表达式捕获病毒的前缀
virus["tgt"] = virus["virus_name"].apply(lambda x: re.findall("[a-z].*(?=vir)", x))
这将从正则表达式返回的列表转换为字符串。
virus["tgt"] = virus["tgt"].astype(str)
virus["tgt"] = virus["tgt"].apply(lambda x: x.strip())
virus["tgt"] = virus["tgt"].apply(lambda x: x.replace("[",""))
virus["tgt"] = virus["tgt"].apply(lambda x: x.replace("]",""))
virus["tgt"] = virus["tgt"].apply(lambda x: x.replace("'",""))
virus["tgt"] = "[a-z]+" + virus["tgt"] + "vir[a-z0-9]+"
virus["tgt"].drop_duplicates(inplace=True)
这一步将panda系列中的所有病毒都放入一个字符串中。另外,感谢您提供此代码 (Python: Elegant way to check if at least one regex in list matches a string)
regexes = virus["tgt"].tolist()
combined = "(" + ")|(".join(regexes) + ")"
这是我最担心的代码。它运行正则表达式,并将找到的内容返回到字符串。 “设置”是删除重复项
def working(x):
x = set(["".join(x) for x in re.findall(combined, x)])
print(x)
return x
这一行运行代码并逐行提取文本。但是,如上所述,这需要很长时间。
df["ID_virus"] = df["Text"].apply(lambda x: working(x))
脚本返回我想要的,但是很慢
对于冗长的条目,我深表歉意,但我想提供尽可能多的信息来重现问题。该脚本有效(我认为),但如前所述,该脚本已经运行了两天。
任何帮助将不胜感激。
【问题讨论】:
-
这是一个相当长的条目......我建议你使用 pandas 矢量化字符串方法