并行填充矩阵

时间:2016-06-25 14:09:04

标签: python loops numpy parallel-processing

我有一个关于如何并行填充矩阵的问题。我正在尝试逐行地在Python中执行此操作。但是并行执行的时间比顺序处理时间要糟糕。我怎样才能有效地做到这一点?注意:我需要知道索引的值( i j )。

Squential

def something(pos, size):
    global matrix

    numpy.zeros(shape=(size, size))

    for i in xrange(size):
        matrix[i][i] = 0.0

        i_lat = pos[i]['lat']
        i_lon = pos[i]['lon']

        for j in xrange(i + 1, size):
             matrix[j][i] = matrix[i][j] = _matrix_update(pos, i_lat, i_lon, i, j)

def _matrix_update(pos, lat, lon, u, v):
    return 0.0 if u == v else euclidean_distance((lat, lon), (pos[v]['lat'], pos[v]['lon']))

并行

def something(pos, size):
    global matrix

    numpy.zeros(shape=(size, size))

    for i in xrange(size):
        matrix[i][i] = 0.0

        i_lat = pos[i]['lat']
        i_lon = pos[i]['lon']

        Parallel(n_jobs=mp.cpu_count())(delayed(_matrix_update)(pos, i_lat, i_lon, i, j) for j in xrange(i, size))

def _matrix_update(pos, lat, lon, u, v):
    global matrix
    matrix[u][v] = matrix[v][u] = (0.0 if u == v else euclidean_distance((lat, lon), (pos[v]['lat'], pos[v]['lon'])))

1 个答案:

答案 0 :(得分:2)

你的代码提出了很多问题,太多了,无法发表评论。

def something(pos, size):
    global matrix      

什么是matrix?为什么global?由于你正在改变它,你不需要全局,即使它是在这个函数之外定义的。但我更希望看到它作为论点传入和传出。

    numpy.zeros(shape=(size, size))

这句话有什么意义?你为什么不把结果分配给任何东西?它应该是matrix = np.zeros(shape...)?在这种情况下,matrix在函数中创建,并且应该在return matrix语句中,而不是全局。

    for i in xrange(size):
        matrix[i][i] = 0.0

如果matrix是2d数组,则使用matrix[i,i] = 0对其进行索引。但如果它是使用zeros表达式创建的,则此对角线已经为0。

        i_lat = pos[i]['lat']
        i_lon = pos[i]['lon']

什么是pos?语法表明它是一个结构化数组,即第i个记录的“lat”字段。这不是词典列表吗?

        for j in xrange(i + 1, size):
             matrix[j][i] = matrix[i][j] = _matrix_update(pos, i_lat, i_lon, i, j)

所以在这里设置对称值。迭代完成后,这是一种很好的方法。用于处理上三角和下三角数组的np.tri...函数。

def _matrix_update(pos, lat, lon, u, v):
    return 0.0 if u == v else euclidean_distance((lat, lon), (pos[v]['lat'], pos[v]['lon']))

考虑到如何迭代i和j,u==v永远不会发生,因此更新可以简化为

j_lat, j_lon = pos[j]['lat'], pos[j]['lon']
matrix[j,i] = matrix[i,j] = euclidean_distance((i_lat, i_lon), (j_lat, j_lon))

我不希望这些变化加快计算速度,但它们应该更清晰。

这是Parallel是什么?您需要提供有关您正在使用的模块或包的更多信息。这是试图使用多核的东西吗?它是否已知与matrix一起使用(它是什么)?

这个euclidian_distance功能是什么?从其他地方导入?