1

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

我有三个x,y,z长度列表N。我应用以下总和

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

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

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

任何想法将不胜感激。

4

3 回答 3

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 处理迭代。希望这对你有用

于 2013-06-21T12:53:14.607 回答
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

我还觉得将数据分类成八叉树之类的东西应该会节省更多,因此您只需查看附近的点,而不是将所有内容与所有内容进行比较,但这超出了我的知识范围。

于 2013-06-21T14:08:48.597 回答
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])))

是的,它看起来绝对是残暴的,但是你去吧。更多信息可以在这里这里找到。

于 2013-06-21T12:38:15.017 回答