用python中的Lambda函数优化多for循环
我有一个下面的数据框用python中的Lambda函数优化多for循环,python,python-3.x,Python,Python 3.x,我有一个下面的数据框Df1,其中列为“摘要”和“结束组” Summary Closing Group XX012 job abended with error Automation XX015 job abended with error Automation Front End issue TSL error Automation XX015 job abended with error Automation Fro
Df1
,其中列为“摘要”和“结束组”
Summary Closing Group
XX012 job abended with error Automation
XX015 job abended with error Automation
Front End issue TSL error Automation
XX015 job abended with error Automation
Front End issue TSL error Automation
Front End issue TSL error Automation
File not present error Automation
我有另一个数据框Df2
,下面有一列“Label”
Label
TSL error
job abended
File not present
如果摘要
中存在标签
中的确切字符串,我想将每个标签
映射到摘要
列
我已经编写了以下脚本,以使用循环的来处理我的情况:
list_label= Df2['Label']
def is_phrase_in(phrase, text):
return re.search(r"\b{}\b".format(phrase), text, re.IGNORECASE) is not None
for idx2,row2 in Df1.iterrows():
for label in list_label:
print(label)
if is_phrase_in(label, row2['Summary']):
Df1.at[idx2,'Label'] =label
break
上面的代码给了我预期的结果,但是在7000标签
列表和20000摘要
上运行时需要花费很多时间
为了优化这一点,我使用了Lambda
函数,如下所示:
Df1['Label'] = Df1['Summary'].apply(lambda x : next((l for l in list_label['Label'] if is_phrase_in(l,x)), 'No Label Found'))
但是这个脚本需要更多的时间,甚至比iffor loop
还要长
有人能告诉我,我在这里是否做错了什么,或者有没有其他方法来优化这段代码
我的预期产出:
Summary Closing Group Label
XX012 job abended with error Automation job abended
XX015 job abended with error Automation job abended
Front End issue TSL error Automation TSL error
Server down error Server No Label found
XX015 job abended with error Automation job abended
Front End issue TSL error Automation TSL error
Front End issue TSL error Automation TSL error
File not present error Automation File not present
必须清楚的是,上面代码中的大部分处理都将花费在正则表达式搜索(re.search)上
你能试试另一种“Python字符串查找()方法”吗。使用数据查找(str,beg=0,end=len(string))
if text.find(phrase) == -1:
return 'No Label Found'
else:
return phrase
使用“in”而不是regex替换字符串的比较会使代码更快一些。但是,从您提供的示例来看,总结似乎在重复(“XX015作业因错误而中止”发生了两次,“前端问题TSL错误”发生了三次)。也许您可以获取一组独特的摘要和标签,然后执行字符串操作,将它们作为字典存储在其他地方,然后执行最终映射。我想这比每次看到字符串时直接计算函数要快得多 你可以试试numpy或panda。它们自然更快,因为它们有针对数据帧的优化引擎。像这样:您真的有7000个唯一的、潜在有效的标签,仅用于20000个数据点吗?必须为每个数据点搜索这些众多标签中的每一个大大扩展了时间要求-如果您可以优化标签列表(如果没有上下文,可能很难理解),那么这将非常有益是的,我有大约7000个独特的标签。我可以建议这是非常容易并行的吗?@Brunodesshuilliers-你是说多线程吗?如果没有,那么你能分享并行化的链接吗?是的,我刚刚做了一个re.search(r“\bA test\b”,“这是一个你知道的测试”,re.IGNORECASE)
vs“a test”。lower()在“这是一个你知道的测试”中。lower()
和正则表达式慢了一个数量级(~2.5s vs~0.15s),这不会给我精确的字符串匹配。例如,我有一个短语='frequency'
和文本='frequency-occurrent error'
,上面的脚本将给我输出为frequency
,但在我的情况下,我不希望这样,因为它不完全匹配。这就是我使用正则表达式的原因。@Oliver.R-我已将短语和文本中的字符串都改为小写,但仍然需要很多时间。在“频繁发生错误”中的“频繁”==False
-短语中的前导空格区分它。如果空间不在那里,而你说frequency
是frequency
的子集,因此你需要使用单词barrier-这是一个昂贵的操作来确定,我认为重新思考你所做的是否是最有效的方式更有意义。关于字符串小写,我不仅仅是指将字符串更改为小写,我还指在
中使用,而不是使用正则表达式解决方案-这要快一个数量级,但是你比较得太多了。@Oliver.R-让我告诉你另一个例子。我的标签包含像'XXX015FS'
和'XMLerror'
这样的值,我的文本包含一个值,比如'XXX015FS XMLerror404 error occurrent'
。现在,如果我使用re.search
函数使用我的脚本,它将给我标签为'xxx015 fs',但如果使用re.find
它可以给我'xxx015 fs'
或'XMLerror'
这两个函数中的任何一个。我有很多这样的案子。这就是我对精确字符串匹配非常挑剔的原因。虽然我的代码运行得很好,并提供了预期的输出,但在7000个标签和20000个摘要上大约需要55分钟。因此,您的迭代将在唯一的摘要上进行,而不是在Df1上。事情会更快,这取决于Df1中的行数和Df1中唯一摘要的数量。老实说,我有20000个唯一摘要标签,它们之间很常见,这就是我将这些摘要映射到标签的原因