How to find unique objects in a numpy array?

Viewed 818

It appears that np.unique does not quite support objects in all cases:

v = np.array(["abc",None,1,2,3,"3",2])
np.unique(v, return_counts=True)

results in

TypeError: '<' not supported between instances of 'NoneType' and 'str'

I can do np.unique(v.astype(str)) but that would lose the distinction between 3 and "3". Is that the only way?

2 Answers

help of numpy.unique says

unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None)
    Find the unique elements of an array.
    
    Returns the sorted unique elements of an array. There are three optional
    outputs in addition to the unique elements:
    
    * the indices of the input array that give the unique values
    * the indices of the unique array that reconstruct the input array
    * the number of times each unique value comes up in the input array
    
    Parameters
    ----------
    ar : array_like
        Input array. Unless `axis` is specified, this will be flattened if it
        is not already 1-D.

Thus it fail as one of your objects has not __lt__ method needed for sorting, if you wish to just found unique but order is irrelevant to you might do

import collections
import numpy as np
v = np.array(["abc",None,1,2,3,"3",2])
cnt = collections.Counter(v.ravel())
uniq = [k for k,v in cnt.items() if v==1]
print(uniq)

Output:

['abc', None, 1, 3, '3']

one way is to define __lt__ for all your objects in your array. Another easier method that will not require sorting and only depends on equality operator (which will work for washable objects only) is using set in python:

np.array(list(set(v)))

output:

array([1, 2, 3, None, '3', 'abc'], dtype=object)
Related