Настройка
points = np.array([[ 0, 0, 1, 1],
[ 0, 0, 2, 2],
[ 1, 0, 3, 0],
[ 1, 0, 4, 1],
[ 0, 1, 5, 10]])
Общая идея здесь - сортировка по первому, второму и четвертому столбцам и обратный результат, поэтомучто когда мы найдем наши уникальные значения, значение с максимальным значением в четвертом столбце будет выше других значений с аналогичными координатами x и y.Затем мы используем np.unique
, чтобы найти уникальные значения в первом и втором столбцах и вернуть те результаты, которые будут иметь максимум v
:
Используя lexsort
и numpy.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]]
array([[ 0, 0, 2],
[ 0, 1, 10],
[ 1, 0, 1]])
Как избежать 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)
array([[ 1, 0, 1],
[ 0, 1, 10],
[ 0, 0, 2]])
Обратите внимание, что в то время как оба будут возвращать правильные результатыони не будут отсортированы, как исходные списки, вы можете просто добавить еще один lexsort
в конце, чтобы исправить это, если хотите.