我在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)
是否有更"笨拙"的方法,能够在性能方面带来一些好处?
设置
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:
lexsort和numpy.uniquedef 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如果您愿意,您可以简单地在末尾添加另一个来解决此问题。