在不使用 lambda 函数的情况下对多处理应用多变量函数
Applying a multivariable function on multiprocessing without using lambda functions
我想应用一个形式的函数(真正的函数有5个参数,假设只有2个)
def func(text,model):
return model[text]
按以下方式添加到数据框:
model = something
df[col2]= df[col1].apply(lambda text: func(text, model)
这工作正常,但速度很慢。这是一个更快的版本,可以正常工作,除非该函数是 lambda 函数。
def apply(func, data):
with Pool(cpu_count()) as pool:
return list(tqdm.tqdm(pool.imap(func, data), total=len(data)))
它抛出以下错误:
PicklingError: Can't pickle <function <lambda> at 0x7fe59c869e50>: attribute lookup <lambda> on __main__ failed
我的解决方案:为了更快的应用这个函数我使用了以下技巧:重新定义函数,使第二个参数为默认值,并且在功能已加载。
model = something
def func(text,model=model):
return model[text]
这很好用,但是我觉得这有点丑。我想知道是否有其他方法可以做到这一点。
我还尝试创建一个 class
class Applyer:
def __init__(self,model):
self.model = model
def func(self,text):
return model[text]
如果我创建一个实例,然后像这样应用函数:
model=something
applyer = Applyer(model)
apply(applyer.func,df[col1])
这行得通,但比使用普通应用(没有多处理)还要慢。这是我的两次尝试。
您可以使用固定参数部分评估您的函数,然后使用缺少的可变参数调用它 functools.partial
:
from functools import partial
partial_func = partial(func, model=some_model)
# now you can call it directly, providing the missing parameter(s):
partial_func(some_text)
# and you can apply it without a lambda:
df[col1].apply(partial_func)
这应该已经加快了运行时间。我没有尝试将其并行化,但由于它是一个简单的函数调用,this question 中给出的方法也应该有效。
我想应用一个形式的函数(真正的函数有5个参数,假设只有2个)
def func(text,model):
return model[text]
按以下方式添加到数据框:
model = something
df[col2]= df[col1].apply(lambda text: func(text, model)
这工作正常,但速度很慢。这是一个更快的版本,可以正常工作,除非该函数是 lambda 函数。
def apply(func, data):
with Pool(cpu_count()) as pool:
return list(tqdm.tqdm(pool.imap(func, data), total=len(data)))
它抛出以下错误:
PicklingError: Can't pickle <function <lambda> at 0x7fe59c869e50>: attribute lookup <lambda> on __main__ failed
我的解决方案:为了更快的应用这个函数我使用了以下技巧:重新定义函数,使第二个参数为默认值,并且在功能已加载。
model = something
def func(text,model=model):
return model[text]
这很好用,但是我觉得这有点丑。我想知道是否有其他方法可以做到这一点。 我还尝试创建一个 class
class Applyer:
def __init__(self,model):
self.model = model
def func(self,text):
return model[text]
如果我创建一个实例,然后像这样应用函数:
model=something
applyer = Applyer(model)
apply(applyer.func,df[col1])
这行得通,但比使用普通应用(没有多处理)还要慢。这是我的两次尝试。
您可以使用固定参数部分评估您的函数,然后使用缺少的可变参数调用它 functools.partial
:
from functools import partial
partial_func = partial(func, model=some_model)
# now you can call it directly, providing the missing parameter(s):
partial_func(some_text)
# and you can apply it without a lambda:
df[col1].apply(partial_func)
这应该已经加快了运行时间。我没有尝试将其并行化,但由于它是一个简单的函数调用,this question 中给出的方法也应该有效。