多返回值函数的joblib并行处理

Posted

技术标签:

【中文标题】多返回值函数的joblib并行处理【英文标题】:joblib parallel processing of a multiple return values function 【发布时间】:2019-01-06 23:10:43 【问题描述】:

我使用 joblib 来并行化一个函数(使用多处理)。但是,这个函数返回 4 个值,但是当我从 Parallel 获得结果时,它只给了我 3 个值

from joblib import Parallel, delayed 
import numpy as np
from array import array
import time

def best_power_strategy():
    powerLoc = 0
    speedLoc = 1
    timeLoc = 2
    previousSpeedLoc = 3        
    return powerLoc,speedLoc,timeLoc,previousSpeedLoc

if __name__ == "__main__":
    realRiderName=['Rider 1', 'Rider 2', 'Rider 3']
    powerLoc = 
    speedLoc = 
    timeLoc = 
    previousSpeedLoc = 
    powerLoc,speedLoc,timeLoc,previousSpeedLoc = Parallel(n_jobs=3)(delayed(best_power_strategy)() for rider in realRiderName)
    print(powerLoc)
    print(speedLoc)
    print(timeLoc)
    print(previousSpeedLoc)

结果是:

ValueError: not enough values to unpack (expected 4, got 3)

有人有想法吗?

提前致谢

【问题讨论】:

您正在为每个 realRiderName 返回一个调用 best_power_strategy() 的生成器。由于realRiderName 中有三个元素,这就是你得到的结果的数量。 嗯,好的,那么如何并行返回 powerLoc、speedLoc、timeLoc 和 previousSpeedLoc? 所以如果我这样做 res = Parallel(n_jobs=3)(delayed(best_power_strategy)() for rider in realRiderName) print(res) 我得到了` [(0, 1, 2, 3), (0, 1, 2, 3), (0, 1, 2, 3)]` 然后我如何将这个列表分成 4 个列表(每个数字一个)? 【参考方案1】:

如果要将结果存储在四个单独的名称中,可以将生成器中的结果压缩在一起,然后将它们展开为所需的名称,即:

# shortening the names for simplicity/readability
riders = ["Rider 1", "Rider 2", "Rider 3"]
p, s, t, pv = zip(*Parallel(n_jobs=3)(delayed(best_power_strategy)() for r in riders))

这将导致p 包含所有powerLoc 结果,s 包含所有speedLoc 结果等等...

现在,鉴于您的 best_power_strategy 函数本质上是静态的,并且没有任何变化(您甚至没有向它发送 rider),因此这段代码非常无用,因为您将一直这样做具有相同的结果,但我认为您只是将其用作示例。

【讨论】:

此代码有效,但实际代码上的 zip 速度真的很慢【参考方案2】:

好的,我已经解决了问题:

from joblib import Parallel, delayed 
import numpy as np
from array import array
import time

def best_power_strategy():
    powerLoc = 0
    speedLoc = 1
    timeLoc = 2
    previousSpeedLoc = 3

    return powerLoc,speedLoc,timeLoc,previousSpeedLoc

if __name__ == "__main__":
    realRiderName=['Rider 1', 'Rider 2', 'Rider 3']
    powerLoc = 
    speedLoc = 
    timeLoc = 
    previousSpeedLoc = 
    res = Parallel(n_jobs=3)(delayed(best_power_strategy)() for rider in realRiderName)
    powerLoc=[item[0] for item in res]
    speedLoc=[item[1] for item in res]
    timeLoc=[item[2] for item in res]
    previousSpeedLoc=[item[3] for item in res]

    print(powerLoc)
    print(speedLoc)
    print(timeLoc)
    print(previousSpeedLoc)

【讨论】:

best_power_strategy每次调用的结果都一样,为什么还要调用三遍? 它只是一个MWE,当然真正的代码要复杂得多

以上是关于多返回值函数的joblib并行处理的主要内容,如果未能解决你的问题,请参考以下文章

joblib保存模型和joblib的并行化处理和tqdm

这个joblib是什么并行语法呢?这么多括号

多处理支持的并行循环不能嵌套在线程下面

多个进程共享一个 Joblib 缓存

从多处理池函数返回值

使用 Joblib 将类对象实例作为输入参数的并行化函数