首页 > 解决方案 > 如何在python中包装列表函数?

问题描述

我无法准确地将这个问题反映到标题中。我想使用listfunc(*args)并且Pool.map没有错误。请看下文。

▼代码

def df_parallelize_run(func, arguments):
    p = Pool(psutil.cpu_count())
    df = p.map(func, arguments)
    p.close()
    p.join()
    return df
def make_lag(df: DataFrame, LAG_DAY: list):
    for l in LAG_DAY:
        df[f'lag{l}d'] = df.groupby(['id'])['target'].transform(lambda x: x.shift(l))

    return df
def wrap_make_lag(args):
    return make_lag(*args)

鉴于以上三个功能,我想做以下

# df: DataFrame
arguments = (df, [1, 3, 7, 13, 16])
df = df_parallelize_run(wrap_make_lag, arguments)

▼ 错误

in df_parallelize_run(func, arguments)
----> 7     df = pool.map(func, arguments)

in ..../python3.7/multiprocessing/pool.py in map(self, func, iterable, chunksize)
--> 268         return self._map_async(func, iterable, mapstar, chunksize).get()

in ..../python3.7/multiprocessing/pool.py in get(self, timeout)
--> 657             raise self._value

TypeError: make_lag() takes 2 positional arguments but 5 were given

我知道这种不匹配的原因(由于解包列表,[1, 3, 7, 13, 16]即 5)。如何正确做?如果可能的话,我想将此列表放在位置参数的约束范围内。如果几乎不可能(listPool.map),有什么更合适、更简单、更灵活的方式?

标签: pythonpandasmultiprocessingargument-unpacking

解决方案


使用pool.starmap. 您为函数的参数生成一个元组列表。在这里,看起来 df 每次都是相同的,而 arg 是参数中的每个元素。

arglist = [(df, arg) for arg in arguments]
with multiprocessing.Pool(multiprocessing.cpu_count()) as p:
    results = p.starmap(make_lag, arglist)


推荐阅读