如何使用Pandas中的apply来并行化许多(模糊)字符串比较?
我有以下问题
我有一个包含句子的数据框大师 ,比如
master
Out[8]:
original
0 this is a nice sentence
1 this is another one
2 stackoverflow is nice
对于Master中的每一行,我使用fuzzywuzzy
查找另一个Dataframe 从站以获得最佳匹配。 我使用fuzzywuzzy因为两个数据框之间的匹配句子可能会有点不同(额外的字符等)。
例如, 奴隶可以
slave
Out[10]:
my_value name
0 2 hello world
1 1 congratulations
2 2 this is a nice sentence
3 3 this is another one
4 1 stackoverflow is nice
这是一个全功能,精彩,紧凑的工作示例:)
from fuzzywuzzy import fuzz
import pandas as pd
import numpy as np
import difflib
master= pd.DataFrame({'original':['this is a nice sentence',
'this is another one',
'stackoverflow is nice']})
slave= pd.DataFrame({'name':['hello world',
'congratulations',
'this is a nice sentence ',
'this is another one',
'stackoverflow is nice'],'my_value': [2,1,2,3,1]})
def fuzzy_score(str1, str2):
return fuzz.token_set_ratio(str1, str2)
def helper(orig_string, slave_df):
#use fuzzywuzzy to see how close original and name are
slave_df['score'] = slave_df.name.apply(lambda x: fuzzy_score(x,orig_string))
#return my_value corresponding to the highest score
return slave_df.ix[slave_df.score.idxmax(),'my_value']
master['my_value'] = master.original.apply(lambda x: helper(x,slave))
100万美元的问题是:我可以并行我的申请代码上面?
毕竟, master
每一行都与slave
所有行进行比较(slave是一个小型数据集,我可以将多个数据副本保存到RAM中)。
我不明白为什么我不能运行多个比较(即在同一时间处理多个行)。
问题:我不知道该怎么做,或者甚至有可能。
任何帮助非常感谢!
您可以将其与Dask.dataframe并行化。
>>> dmaster = dd.from_pandas(master, npartitions=4)
>>> dmaster['my_value'] = dmaster.original.apply(lambda x: helper(x, slave), name='my_value'))
>>> dmaster.compute()
original my_value
0 this is a nice sentence 2
1 this is another one 3
2 stackoverflow is nice 1
此外,您应该考虑在这里使用线程与进程之间的权衡。 你的模糊字符串匹配几乎肯定不会释放GIL,所以你不会从使用多线程中获得任何好处。 但是,使用进程会导致数据序列化并在您的机器周围移动,这可能会使速度变慢。
您可以通过管理compute()
方法的get=
关键字参数来尝试使用线程和进程或分布式系统。
import dask.multiprocessing
import dask.threaded
>>> dmaster.compute(get=dask.threaded.get) # this is default for dask.dataframe
>>> dmaster.compute(get=dask.multiprocessing.get) # try processes instead
我正在做类似的工作,我想为任何可能遇到此问题的人提供更完整的工作解决方案。 不幸的是,@MRocklin在提供的代码片段中有一些语法错误。 我不是Dask的专家,所以我不能评论一些性能方面的考虑,但是这应该像@MRocklin所建议的那样完成你的任务。 这是使用Dask版本0.17.2和Pandas版本0.22.0 :
import dask.dataframe as dd
import dask.multiprocessing
import dask.threaded
from fuzzywuzzy import fuzz
import pandas as pd
master= pd.DataFrame({'original':['this is a nice sentence',
'this is another one',
'stackoverflow is nice']})
slave= pd.DataFrame({'name':['hello world',
'congratulations',
'this is a nice sentence ',
'this is another one',
'stackoverflow is nice'],'my_value': [1,2,3,4,5]})
def fuzzy_score(str1, str2):
return fuzz.token_set_ratio(str1, str2)
def helper(orig_string, slave_df):
slave_df['score'] = slave_df.name.apply(lambda x: fuzzy_score(x,orig_string))
#return my_value corresponding to the highest score
return slave_df.loc[slave_df.score.idxmax(),'my_value']
dmaster = dd.from_pandas(master, npartitions=4)
dmaster['my_value'] = dmaster.original.apply(lambda x: helper(x, slave),meta=('x','f8'))
然后,获得你的结果(就像在这个口译员会议中一样):
In [6]: dmaster.compute(get=dask.multiprocessing.get)
Out[6]:
original my_value
0 this is a nice sentence 3
1 this is another one 4
2 stackoverflow is nice 5
链接地址: http://www.djcxy.com/p/53529.html
上一篇: how to parallelize many (fuzzy) string comparisons using apply in Pandas?