加快python中循环的总和

时间:2013-06-21 12:27:51

标签: python numpy scipy

我有以下瓶颈,我想知道是否有人可以建议加快速度的方法。

我有三个长度x,y,z的{​​{1}}列表。我应用以下summation

N

我尝试使用numpy数组,但要么我做错了,要么速度降低了大约2倍。

任何想法都将受到高度赞赏。

3 个答案:

答案 0 :(得分:3)

我相信你可以通过做类似下面的事情来更有效地利用numpy。对函数进行一些小修改以使用numpy.sqrt:

import numpy as np

def abs_val_diff(x1, x2, x3, y1, y2, y3):
    """ Find the absolute value of the difference between x and y """
    return np.sqrt((x1 - y1) ** 2.0 + (x2 - y2) ** 2.0 + (x3 - y3) ** 2.0)

然后使用完整数组调用:

res = abs_val_diff(x[:-1],y[:-1],z[:-1],x[1:],y[1:],z[1:])

然后,因为您为每个匹配添加1,所以您可以简单地根据结果获取数组的长度:

sumV = len(res[R>res])

这让numpy处理迭代。希望这对你有用

答案 1 :(得分:2)

你有什么理由需要在你的函数中取平方根吗?如果您对结果所做的只是将其与限制进行比较,为什么不仅仅比较比较的两边?

def abs_val_diff_squared(x1, x2, x3, y1, y2, y3):
    """ Find the square of the absolute value of the difference between x and y """
    return (x1 - y1) ** 2.0 + (x2 - y2) ** 2.0 + (x3 - y3) ** 2.0

R = 0.1
R_squared = R * R
sumV = 0.0
for i in xrange(N):
    for j in xrange(i + 1, N):
        if R_squared > abs_val_diff_squared(x[i], y[i], z[i],
                            x[j], y[j], z[j]):
                sumV += 1.0

我也觉得通过将数据排序成像octtree这样的东西可以获得更大的节省,所以你只需要查看附近的点而不是将所有内容与所有内容进行比较,但这不在我的掌握之中。

答案 2 :(得分:0)

事实证明,冗长,丑陋,列表推导通常比python中的显式循环更快,因为它们可以编译为更高效的字节码。我不确定它对你有帮助,但尝试这样的事情:

sumV = sum((1.0 for j in xrange(1+1, N) for i in xrange(N) if R > abs_val_diff(x[i], y[i], z[i], x[j], y[j], z[j])))

是的,它看起来非常残酷,但你去了。可以找到更多信息herehere