【问题标题】:Applying a multivariable function on multiprocessing without using lambda functions在不使用 lambda 函数的情况下将多变量函数应用于多处理
【发布时间】:2022-01-25 17:03:35
【问题描述】:

我想应用一个形式的函数(真正的函数有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 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])

这可行,但比使用普通应用(没有多处理)还要慢。这是我的两次尝试。

【问题讨论】:

    标签: python-3.x dataframe lambda multiprocessing


    【解决方案1】:

    您可以使用固定参数部分评估您的函数,然后使用 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 中给出的方法也应该可以工作。

    【讨论】:

    • 感谢您的回答,这正是我所需要的;)
    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 2010-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-19
    • 2017-03-14
    • 2017-01-18
    相关资源
    最近更新 更多