This is collapsed, but it is probably as good as you are going to use only numpy ...
First we use lexsort to put all records with the same coordinates. If a is your pattern array:
>>> perm = np.lexsort(a[:, 3::-1].T) >>> a[perm] array([[ 0.12080023, 0.74853649, 0.15356663, 0.4505753 ], [ 0.7732126 , 0.48649481, 0.29771819, 0.91622924], [ 0.7732126 , 0.48649481, 0.29771819, 1.91622924], [ 0.1877724 , 0.96060999, 0.39697999, 0.59078612], [ 0.3239913 , 0.7786444 , 0.41692853, 0.10467392], [ 0.58294263, 0.32025559, 0.6925856 , 0.0524125 ], [ 0.58294263, 0.32025559, 0.6925856 , 0.05 ], [ 0.58294263, 0.32025559, 0.6925856 , 1.7 ], [ 0.13536096, 0.60319054, 0.82018125, 0.10445047]])
Note that by turning the axis, we sort by x , breaking the connections with y , then z , then w .
Since this is the maximum we are looking for, we just need to take the last entry in each group, which is pretty simple:
>>> a_sorted = a[perm] >>> last = np.concatenate((np.all(a_sorted[:-1, :3] != a_sorted[1:, :3], axis=1), [True])) >>> a_unique_max = a_sorted[last] >>> a_unique_max array([[ 0.12080023, 0.74853649, 0.15356663, 0.4505753 ], [ 0.13536096, 0.60319054, 0.82018125, 0.10445047], [ 0.1877724 , 0.96060999, 0.39697999, 0.59078612], [ 0.3239913 , 0.7786444 , 0.41692853, 0.10467392], [ 0.58294263, 0.32025559, 0.6925856 , 1.7 ], [ 0.7732126 , 0.48649481, 0.29771819, 1.91622924]])
If you prefer not to sort the result, but keep them in the original order, they are in the original array, you can also get this with perm :
>>> a_unique_max[np.argsort(perm[last])] array([[ 0.7732126 , 0.48649481, 0.29771819, 1.91622924], [ 0.58294263, 0.32025559, 0.6925856 , 1.7 ], [ 0.3239913 , 0.7786444 , 0.41692853, 0.10467392], [ 0.12080023, 0.74853649, 0.15356663, 0.4505753 ], [ 0.13536096, 0.60319054, 0.82018125, 0.10445047], [ 0.1877724 , 0.96060999, 0.39697999, 0.59078612]])
This will only work for the maximum, and it will become a by-product of the sort. If you perform another function, say, the product of all records with the same coordinates, you can do something like:
>>> first = np.concatenate(([True], np.all(a_sorted[:-1, :3] != a_sorted[1:, :3], axis=1))) >>> a_unique_prods = np.multiply.reduceat(a_sorted, np.nonzero(first)[0])
And you will have to play around a bit with these results to assemble the returned array.