- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我有一个嵌套的列表理解,看起来像这样:
>>> nested = [[1, 2], [3, 4, 5]]
>>> [[sqrt(i) for i in j] for j in nested]
[[1.0, 1.4142135623730951], [1.7320508075688772, 2.0, 2.23606797749979]]
是否可以使用 standard joblib approach for embarrassingly parallel for loops 将其并行化?如果是这样,delayed
的正确语法是什么?
据我所知,文档没有提及或给出嵌套输入的任何示例。我尝试了一些天真的实现,但无济于事:
>>> #this syntax fails:
>>> Parallel(n_jobs = 2) (delayed(sqrt)(i for i in j) for j in nested)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Python27\lib\site-packages\joblib\parallel.py", line 660, in __call__
self.retrieve()
File "C:\Python27\lib\site-packages\joblib\parallel.py", line 512, in retrieve
self._output.append(job.get())
File "C:\Python27\lib\multiprocessing\pool.py", line 558, in get
raise self._value
pickle.PicklingError: Can't pickle <type 'generator'>: it's not found as __builtin__.generator
>>> #this syntax doesn't fail, but gives the wrong output:
>>> Parallel(n_jobs = 2) (delayed(sqrt)(i) for i in j for j in nested)
[1.7320508075688772, 1.7320508075688772, 2.0, 2.0, 2.23606797749979, 2.23606797749979]
如果这是不可能的,我显然可以在将列表传递给 Parallel
之前和之后重组列表。然而,我的实际列表很长,每一项都很大,所以这样做并不理想。
最佳答案
我不太确定您第二次尝试时发生了什么,但我很清楚第一次尝试:sqrt
后面括号中的表达式,(i for i in j)
结果为 "generator"对象,它被传递到并行处理管道。不幸的是,生成器的输出可能依赖于之前的调用。在您的情况下,它会在每次调用时提供 j 的下一个元素,但它也可能会进行一些内部计算,这意味着不同的过程相互依赖,并且您的结果可能会依赖于顺序其中执行并行进程。因此,multiprocessing
库拒绝继续。
正如我所说,我不太确定第二个示例中发生了什么,但可能只是您设法不小心欺骗了 multiprocessing
来执行它在第一个示例中试图避免的操作.
可能的解决方案:
1:分离迭代层次
...例如,正如 j_n 所建议的那样,通过定义一个将在低级列表上迭代的函数。这很容易实现,但可能无法从并行化中获得太多好处,具体取决于各个列表的长度。对外部循环使用非并行列表理解但对内部循环或什至两者并行化也可能是一种选择——这是否有用在很大程度上取决于您的数据结构。
2:迭代嵌套列表的线性化版本
这样,每次执行都是并行完成的,但这意味着您需要先“展平”列表,然后再重组它。
如果你的嵌套列表是规则结构的(即如果它包含 n 个列表,每个列表有 m 个元素:
制作numpy array从嵌套列表中,像这样:
import numpy as np
# convert to array -- only works well if you have a regular structure!
nested_arr = np.array(nested)
# the shape of the array, for later
shape = nested_arr.shape
# generate an (n*m) linear array from an (n, m) 2D one
linear = nested_arr.ravel()
# run the parallel calculation
results_lin = Parallel(n_jobs = 2) (delayed(sqrt)(e) for e in linear)
# get everything back into shape:
results = results_lin.reshape(shape)
实际上,这可能更简单,因为 np.nditer()
在多维数组上按元素迭代。不过,我不确定它是否会与 joblib
和 multiprocessing
合作。如果您有常规数据(并且您真的只想做比求平方根更复杂的事情),您还应该考虑简单地使用 np.sqrt(nested_arr)
- 这执行起来比遍历数字列表并按数量级分别对它们进行平方!
如果您的嵌套列表是不规则的,线性化会变得更加复杂:
# store lengths of the sub-lists
structure = [len(e) for e in nested]
# make one linear list
linlist = []
for l in nested:
linlist.extend(l)
# finally run the parallel computation:
results_lin = Parallel(n_jobs = 2) (delayed(sqrt)(e) for e in linlist)
# ...and bring it all back into shape:
results = []
i = 0
for n in structure:
results.append(results_lin[i:i+n])
这一切是否再次有意义取决于您处理的数据量和列表的复杂性。对于您的简单示例,显然排序将比计算平方根花费更长的时间。
不过,您真的需要并行化吗?
如果您所做的只是对大量数字进行简单的数学运算,请考虑使用 np.array
。您可以将数组放入大多数方程式中,就好像它们是数字一样,并且计算运行得更快:
In [14]: time resl = [sqrt(e) for e in range(1000000)]
CPU times: user 2.1 s, sys: 194 ms, total: 2.29 s
Wall time: 2.19 s
In [15]: time res = np.sqrt(np.arange(1000000))
CPU times: user 10.4 ms, sys: 0 ns, total: 10.4 ms
Wall time: 10.1 ms
这比列表中的操作可以加速到的速度快,甚至可以在 24 核上并行运行。 (事实上 ,您需要大约 216 个并行进程才能跟上 numpy
,而且我敢肯定 mutliprocessing
将负载分配给那么多进程的计算工作量注定会失败无论如何尝试。
关于python - joblib.Parallel 用于嵌套列表理解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30200947/
我正在努力解决 joblib 问题。 我需要将推理应用程序推送到远程服务器,并且我还需要加载保存的标准缩放器,因为如果我尝试适应,我会收到内存不足异常。我无法对服务器进行物理更改,因为它是 sap c
我在 Docker 容器内的 Flask 应用程序中运行 joblib 以及由 supervisord 启动的 uWSGI(启动时启用线程)。 网络服务器启动显示如下错误: unable to loa
我正在尝试在 python 中使用并行计算包 joblib。我可以执行下面的例子并得到结果 Parallel(n_jobs=8)(delayed(sqrt)(i) for i in range(10)
这是我的代码: from math import sqrt from joblib import Parallel, delayed import multiprocessing def parall
我正在使用Python中joblib包中的Parallel函数。我只想使用此函数来处理我的函数之一,但不幸的是整个代码是并行运行的(除了其他函数)。 示例: from joblib import Pa
我正在努力学习 joblib模块作为 python 中内置 multiprocessing 模块的替代品。我习惯于使用 multiprocessing.imap 在可迭代对象上运行一个函数并返回结果。
我正在尝试使用 joblib 来并行化一个在函数上运行的循环。我希望显示函数的中间 print 命令,而不仅仅是函数的 return 值。 from joblib import Parallel, d
我想打乱 3D numpy 数组中的值,但前提是它们 > 0。 当我用单核运行我的函数时,它甚至比使用 2 个核快得多。这远远超出了创建新 python 进程的开销。我错过了什么? 以下代码输出: r
我的目标结构: 工具 model_maker.py 模特 模型在这里 我当前的代码,位于工具目录中 joblib.dump(pipeline, "../models/model_full_June20
是否可以使用 joblib.Memory 以线程安全的方式写入跨多个进程的公共(public)缓存。在什么情况下,这会失败或导致错误? 最佳答案 库首先写入临时文件,然后将临时文件移动到目的地。 So
我目前正在尝试实现 parallel for循环使用 joblib在 python 中 3.8.3 . 在 for 循环中,我想将一个类方法应用于一个类的实例,同时在另一个类中应用一个方法。 这是一个
我的代码看起来像这样: from joblib import Parallel, delayed # prediction model - 10s of megabytes on disk LARGE
from joblib import Parallel, delayed def func(v): temp.append(v) return temp = [] Parallel(n
有关于使用内存映射文件在 Joblib 中持久保存 Numpy 数组的良好文档。 在最近的版本中,Joblib(显然)会以这种方式自动保留和共享 Numpy 数组。 Pandas 数据帧也会被持久化,
我正在运行一个需要一段时间才能评估 16 次的函数。然而,所有这些运行都是相互独立的。因此我决定使用 joblib 来加速它。 Joblib 的工作方式就像它应该的那样并加快了速度,但我正在努力解决一
我正在使用 joblib 并行化我的 python 3.5 代码。 如果我这样做: from modules import f from joblib import Parallel, delaye
我正在使用 Random Forest Regressor python 的 scikit-learn 模块来预测一些值。我使用 joblib.dump 来保存模型。有 24 个 joblib.dum
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 这个问题似乎是题外话,因为它缺乏足够的信息来诊断问题。 更详细地描述您的问题或include a min
我想问同样的问题 Python 3: does Pool keep the original order of data passed to map?对于作业库。例如: Parallel(n_jobs
我需要在使用 Joblib 并行的函数中生成随机数。但是,从内核生成的随机数是完全相同的。 目前我通过为不同的核心分配随机种子来解决这个问题。有什么简单的方法可以解决这个问题吗? 最佳答案 这是预料之
我是一名优秀的程序员,十分优秀!