需要帮助在python中并行化循环吗

需要帮助在python中并行化循环吗,python,numpy,parallel-processing,multiprocessing,Python,Numpy,Parallel Processing,Multiprocessing,我有一个巨大的数据集,我必须为它的每一点计算一系列属性。我的代码非常慢,我想让它更快地并行化do循环。我希望每个处理器为我的数据的有限子样本计算“属性系列”,然后将所有属性合并到一个数组中。 我将试着用一个例子来解释我必须做什么 假设我的数据集是数组x: x = linspace(0,20,10000) prop=[] for i in arange(0,len(x)): prop.append(sqrt(x[i])) 例如,我想要得到的“属性”是x的平方根: x = linspac

我有一个巨大的数据集,我必须为它的每一点计算一系列属性。我的代码非常慢,我想让它更快地并行化do循环。我希望每个处理器为我的数据的有限子样本计算“属性系列”,然后将所有属性合并到一个数组中。 我将试着用一个例子来解释我必须做什么

假设我的数据集是数组
x

x = linspace(0,20,10000)
prop=[]
for i in arange(0,len(x)):
    prop.append(sqrt(x[i]))
例如,我想要得到的“属性”是
x
的平方根:

x = linspace(0,20,10000)
prop=[]
for i in arange(0,len(x)):
    prop.append(sqrt(x[i]))
问题是如何并行化上述循环?假设我有4个处理器,我希望每个处理器都能计算出10000/4=2500点的sqrt

我试着查看一些python模块,如
多处理
mpi4py
,但从指南中我找不到这样一个简单问题的答案

编辑

我将感谢你们为我提供的宝贵评论和链接。不过,我想澄清我的问题。我对
sqrt
函数不感兴趣。 我在一个循环中执行一系列操作。我完全知道循环是不好的,向量运算总是比它们好,但在这种情况下,我真的必须做一个循环。我不会详细讨论我的问题,因为这会给这个问题增加不必要的复杂性。 我想分割我的循环,让每个处理器都做一部分,这意味着我可以用每个循环的1/40运行我的代码40次,然后合并结果,但这太愚蠢了。 这是一个简单的例子

     for i in arange(0,len(x)):
         # do some complicated stuff
我想要的是使用40个CPU来执行此操作:

    for npcu in arange(0,40):
       for i in arange(len(x)/40*ncpu,len(x)/40*(ncpu+1)):
          # do some complicated stuff

这在python中是可能的还是不可能的?

并行化不是一件小事,但是您可能会发现它很有用

对于数值计算,您真的应该研究numpy提供给您的实用程序(以及类似的工具),这些工具通常会给您带来很好的加速,作为工作的基础

对于更复杂的非数值情况,您可以使用
多处理
(参见注释)


另一方面,与其他语言相比,python的多线程处理更为重要,这是因为CPython具有不允许在同一解释器中同时运行两段python代码(即,没有真正的多线程纯python代码)。但是,对于I/O和繁重的计算,第三方库倾向于释放该锁,因此可以进行有限的多线程处理


这增加了通常的多线程干扰,即必须对共享数据访问和类似的访问进行互斥。

我不确定您是否应该这样做,因为我希望numpy有一种更有效的方法来处理它,但您的意思是这样的吗

import numpy
import multiprocessing

x = numpy.linspace(0,20,10000)
p = multiprocessing.Pool(processes=4)

print p.map(numpy.sqrt, x)
以下是两种解决方案的
timeit
结果。然而,正如@SvenMarcach所指出的,使用更昂贵的函数,多处理将开始变得更加有效

% python -m timeit -s 'import numpy; x=numpy.linspace(0,20,10000)' 'prop=[]                                                                          
for i in numpy.arange(0,len(x)):
         prop.append(numpy.sqrt(x[i]))'
10 loops, best of 3: 31.3 msec per loop

% python -m timeit -s 'import numpy, multiprocessing; x=numpy.linspace(0,20,10000)
p = multiprocessing.Pool(processes=4)' 'l = p.map(numpy.sqrt, x)' 
10 loops, best of 3: 102 msec per loop
根据Sven的要求,这里是
l=numpy.sqrt(x)
的结果,它比任何一个备选方案都要快得多

% python -m timeit -s 'import numpy; x=numpy.linspace(0,20,10000)' 'l = numpy.sqrt(x)'
10000 loops, best of 3: 70.3 usec per loop

我建议你看看cython:


它使您能够非常快速地为python创建c扩展,并与numpy很好地集成。下面是一个很好的教程,可以帮助您入门:

对于这个特定的示例,如果使用
numpy.sqrt(x)
而不是Python循环,您将获得比仅仅4倍更好的加速效果。你的真实任务也可能是这样。谢谢你的回答,但我的真实任务要比执行sqrt复杂得多。我只是想知道为什么我找不到任何简单python for循环并行化的例子。根据我的经验,矢量化是在99%的情况下加速数值python循环的方法,即使它们更复杂。描述一下你真正的函数,我可能会告诉你如何向量化它。我使用的是向量运算。我有一个庞大的数据集(N>1e6个点),对于任何点,我都必须执行10/20矢量运算。对于每个数据点,这将花费1秒钟的时间,因此我最终的计算时间总共为1.6秒,这是不可行的。感谢链接。但我希望能找到python中最简单的并行循环示例的链接。@Matteo:给你:谢谢,但从这个示例中,我不太清楚(至少我不清楚)如何在每个处理器之间分割任务。@Matteo:
Pool.map()
自动执行此操作。只需阅读文档。@SvenMarnach谢谢,我甚至不知道。也许你应该把它作为一个更详细的描述的备选答案?这一点肯定要归功于您。
多处理
方法速度较慢,因为每次迭代执行的函数都相当简单。如果您在每次迭代中都有一个“fat”函数,那么实际上您将看到一个加速。在timimngs中加入
l=numpy.sqrt(x)
也会很有趣。@SvenMarnach这是一个很好的观点,我唯一一次使用
多处理
是为了像获取许多网页这样的任务,显然要快得多。我没有考虑到sqrt实际上是一个非常简单的函数,我试图编辑我的帖子来反映这一点,并添加
numpy.sqrt(x)
的结果。请注意,最后一个解决方案实际上比普通Python循环快450倍。它不在另外两个之间!这也是我上述评论的重点。@SvenMarnach,现在我觉得自己像个白痴(原来我应该更关注msec vs usec D:)。非常感谢你指出这一点,我很震惊,它是“慢”。这似乎是你最初论点的一个很好的例子。这就是为什么我要求你把它包括在内谢谢