Вы можете отсортировать массив лексикографически по строкам и искать точки, где строки изменяются:
In [1]: a = array([[0, 0, 1], [1, 1, 1], [1, 1, 1], [1, 0, 1]])
In [2]: b = a[lexsort(a.T)]
In [3]: b
Out[3]:
array([[0, 0, 1],
[1, 0, 1],
[1, 1, 1],
[1, 1, 1]])
...
In [5]: (b[1:] - b[:-1]).any(-1)
Out[5]: array([ True, True, False], dtype=bool)
Последний массив говорит, что первые три строки отличаются, а третья строка повторяется дважды.
Для массивов единиц и нулей вы можете закодировать значения:
In [6]: bincount(dot(a, array([4,2,1])))
Out[6]: array([0, 1, 0, 0, 0, 1, 0, 2])
Также можно использовать словари. Какой из различных методов будет наиболее быстрым, зависит от типа массивов, с которыми вы на самом деле работаете.