Numpy:从点列表中获得最大值的正确方法

tha*_*sme 5 python numpy max

我在3d坐标系(X,Y,Z)中有一个点列表.而且,它们中的每一个都分配了浮点值v,因此单个点可以被描述为(x,y,z,v).该列表表示为shape =(N,4)的numpy数组.对于每个2d位置x,y我需要得到v的最大值.一种简单但计算量很大的方法是:

for index in range(points.shape[0]):
    x = points[index, 0]
    y = points[index, 1]
    v = points[index, 3]

    maxes[x, y] = np.max(maxes[x, y], v)
Run Code Online (Sandbox Code Playgroud)

是否有更"笨拙"的方法,能够在性能方面带来一些好处?

use*_*203 4

设置

points = np.array([[ 0,  0,  1,  1],
                   [ 0,  0,  2,  2],
                   [ 1,  0,  3,  0],
                   [ 1,  0,  4,  1],
                   [ 0,  1,  5, 10]])
Run Code Online (Sandbox Code Playgroud)

这里的总体思路是使用第一、第二和第四列进行排序,然后反转结果,这样当我们找到唯一值时,第四列中具有最大值的值将高于具有相似 x 和 y 的其他值坐标。然后我们用来np.unique查找第一列和第二列中的唯一值,并返回这些结果,其中将具有最大值v

使用lexsortnumpy.unique

def max_xy(a):
    res = a[np.lexsort([a[:, 3], a[:, 1], a[:, 0]])[::-1]]
    vals, idx = np.unique(res[:, :2], 1, axis=0)
    maximums = res[idx]
    return maximums[:, [0,1,3]]
Run Code Online (Sandbox Code Playgroud)

array([[ 0,  0,  2],
       [ 0,  1, 10],
       [ 1,  0,  1]])
Run Code Online (Sandbox Code Playgroud)

避免unique以获得更好的性能

def max_xy_v2(a):
    res = a[np.lexsort([a[:, 3], a[:, 1], a[:, 0]])[::-1]]
    res = res[np.append([True], np.any(np.diff(res[:, :2],axis=0),1))]
    return res[:, [0,1,3]]

max_xy_v2(points)
Run Code Online (Sandbox Code Playgroud)

array([[ 1,  0,  1],
       [ 0,  1, 10],
       [ 0,  0,  2]])
Run Code Online (Sandbox Code Playgroud)

请注意,虽然两者都会返回正确的结果,但它们不会像原始列表那样排序,lexsort如果您愿意,您可以简单地在末尾添加另一个来解决此问题。