用Python代码并行计算两点之间距离的最快方法

用Python代码并行计算两点之间距离的最快方法,python,performance,parallel-processing,Python,Performance,Parallel Processing,我有一个包含数百万行的数据框“data”。每一行都有坐标('x','y'),我想以python能够提供的最有效的方式计算连续坐标对之间的距离。并行化在这里有用吗 我在这里看到了一些建议使用cython的方法。但是,我只希望看到python解决方案 这是我的数据片段 points = [(26406, -6869), (27679, -221), (27679, -221), (26416, -6156), (26679, -578), (26679, -580), (27813,

我有一个包含数百万行的数据框“data”。每一行都有坐标('x','y'),我想以python能够提供的最有效的方式计算连续坐标对之间的距离。并行化在这里有用吗

我在这里看到了一些建议使用cython的方法。但是,我只希望看到python解决方案

这是我的数据片段

points = 
[(26406, -6869),
 (27679, -221),
 (27679, -221),
 (26416, -6156),
 (26679, -578),
 (26679, -580),
 (27813, -558),
 (26254, -1097),
 (26679, -580),
 (27813, -558),
 (28258, -893),
 (26253, -1098),
 (26678, -581),
 (27811, -558),
 (28259, -893),
 (26252, -1098),
 (27230, -481),
 (26679, -582),
 (27488, -5849),
 (27811, -558),
 (28259, -893),
 (26250, -1099),
 (27228, -481),
 (26679, -582),
 (27488, -5847),
 (28525, -1465),
 (27811, -558),
 (28259, -892)]
我相信我的第一种使用for循环的方法肯定可以改进:

    from scipy.spatial import distance
    def comp_dist(points):
        size  =len(points)
        d = 0
        i=1
        for i in range(1,size):
            if i%1000000==0:
                print i
            # print "i-1:", points[i-1]
            # print "i: ", points[i]
            dist = distance.euclidean(points[i-1],points[i])
            d= d+dist
        print d

    distance = comp_dist(points)

提前感谢您的回答

以下是一个帮助您入门的快速示例:

从scipy.spatial导入距离
来自多处理导入池
进程=4
#将数据分组成对以计算距离
配对=[(点[i],点[i+1]),用于范围内的i(len(点)-1)]
打印对
#将数据分割成块
l=[i:i+进程对]用于x范围内的i(0,len(对),进程)]
def工作人员(lst):
返回[lst中i的距离欧氏(i[0],i[1])]
如果名称=“\uuuuu main\uuuuuuuu”:
p=池(进程)
结果=p.map(工人,l)
#展平列表
打印[子列表中项目的子列表结果中的项目]
用以下方法测试此功能:

points =[(random.randint(0,1000), random.randint(0, 1000)) for i in range(1000000)]

使用8个进程大约需要5秒,使用1个进程需要10秒以上。

您说的是python,但是由于您已经在使用scipy进行距离计算,我认为numpy解决方案是可以的

在我的笔记本电脑上,在2800万点numpy阵列上使用矢量化单线程操作只需1秒。该阵列使用32位整数数据类型,占用大约200MB的内存

将numpy导入为np
分数=[(26406,-6869),…,(28259,-892)]
#使测试数组重复28个元素点列表1M次
np_points=np.array(points*1000000,dtype='int32')
#从结果数组中使用两个不同的切片(偏移1);
#执行下一行大约需要1秒
距离=np.sqrt(np.sum((np_点[0:-2]-np_点[1:-1])**2,轴=1))
打印(距离形状)
(27999998,)
打印(距离[:28])
[6.76878372e+03 0.00000000 E+00 6.06789865e+03 5.58419672e+03
2.00000000 E+00 1.13421338e+03 1.64954600e+03 6.69263775e+02
1.13421338e+03 5.57000898e+02 2.01545280e+03 6.69263775e+02
1.13323343e+035.59400572e+022.01744244e+031.15636197e+03
5.60180328e+02 5.32876815e+03 5.30084993e+03 5.59400572e+02
2.01953386e+03 1.15689585e+03 5.58213221e+02 5.32679134e+03
4.50303153e+031.15431581e+035.58802291e+026.25764636e+03]

使用numpy将比您当前的解决方案更快,并且比Cython更容易实现。不过,它不会给你带来并行化(例如,它可能会针对你的CPU进行优化)。如果你要走多处理路线,你需要将你的大列表拆分成块,处理它们,然后在末尾合并它们。你认为这会提高性能吗?这取决于数据的大小,并行启动作业会带来成本,但随着数据大小的增加,成本会被抵消。如果您的任务在毫秒内完成,则通常不值得。我有4900万个协调。您可以将其与进程级并行化结合起来,但这不太可能有帮助,因为复制和进程初始化的开销相对于工作量来说是很大的。