python - 对数组进行高效的双重迭代

标签 python arrays numpy

我有以下代码,其中 points 是 3 列列表的多行,coorRadius 是一个半径,我想在其中找到局部坐标最大值,localCoordinateMaxima 是一个数组,我在其中存储这些最大值的 i:

for i,x in enumerate(points):
        check = 1
        for j,y in enumerate(points):
            if linalg.norm(x-y) <= coorRadius and x[2] < y[2]:
                check = 0

        if check == 1:
            localCoordinateMaxima.append(i)

    print localCoordinateMaxima

不幸的是,当我有几千点时,这会花费很长时间,我正在寻找加快速度的方法。我试着用 if all() 条件来做,但是我没有管理它,我什至不确定它会更有效率。你们能提出一种让它更快的方法吗?

最好!

最佳答案

最好使用 KDTree 搜索邻居。

from scipy.spatial import cKDTree

tree = cKDTree(points)
pairs = tree.query_pairs(coorRadius)

现在pairs是一组两项元组 (i, j) , 其中i < jpoints[i]points[j]coorRadius 内彼此的。您现在可以简单地迭代这些,这可能比 len(points)**2 小得多。您目前正在迭代:

is_maximum = [True] * len(points)
for i, j in pairs:
    if points[i][2] < points[j][2]:
        is_maximum[i] = False
    elif points[j][2] < points[i][2]:
        is_maximum[j] = False
localCoordinateMaxima, = np.nonzero(is_maximum)

这可以通过矢量化进一步加速:

pairs = np.array(list(pairs))
pairs = np.vstack((pairs, pairs[:, ::-1]))
pairs = pairs[np.argsort(pairs[:, 0])]
is_z_smaller = points[pairs[:, 0], 2] < points[pairs[:, 1], 2]
bins, = np.nonzero(pairs[:-1, 0] != pairs[1:, 0])
bins = np.concatenate(([0], bins+1))
is_maximum = np.logical_and.reduceat(is_z_smaller, bins)
localCoordinateMaxima, = np.nonzero(is_maximum)

上面的代码假设每个点在coorRadius内至少有一个邻居.如果不是这种情况,您需要稍微复杂一点:

pairs = np.array(list(pairs))
pairs = np.vstack((pairs, pairs[:, ::-1]))
pairs = pairs[np.argsort(pairs[:, 0])]
is_z_smaller = points[pairs[:, 0], 2] < points[pairs[:, 1], 2]
bins, = np.nonzero(pairs[:-1, 0] != pairs[1:, 0])
has_neighbors = pairs[np.concatenate(([True], bins)), 0]
bins = np.concatenate(([0], bins+1))
is_maximum = np.ones((len(points),), bool)
is_maximum[has_neighbors] &= np.logical_and.reduceat(is_z_smaller, bins)
localCoordinateMaxima, = np.nonzero(is_maximum)

关于python - 对数组进行高效的双重迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25347821/

相关文章:

python - CPython的静态对象地址和碎片

python - ValueError 和 odepack.error 使用 integrate.odeint()

java - 在 Java 中将二维数组的列作为参数传递

java - 接受对象数组然后添加到 ArrayList 的类

python - 如何在使用 bazel 构建的项目中使用 vscode python 调试器?

python - 内核以退出代码 1(VS 代码)死亡

python - AWS 上多个 API 之间的共享 Python 库

python-3.x - python : SettingWithCopyWarning when trying to set value to True based on condition

python - 正在使用 PIL 保存损坏的图像

python - 获得滚动百分位数排名的快速方法