Map a NumPy array of strings to integers
<p><strong>Problem:</strong></p>

<p>Given an array of string data</p>

<pre><code>dataSet = np.array(['kevin', 'greg', 'george', 'kevin'], dtype='U21'), 
</code></pre>

<p>I would like a function that returns the indexed dataset</p>

<pre><code>indexed_dataSet = np.array([0, 1, 2, 0], dtype='int')
</code></pre>

<p>and a lookup table</p>

<pre><code>lookupTable = np.array(['kevin', 'greg', 'george'], dtype='U21')
</code></pre>

<p>such that</p>

<pre><code>(lookupTable[indexed_dataSet] == dataSet).all()
</code></pre>

<p>is true. Note that the <code>indexed_dataSet</code> and <code>lookupTable</code> can both be permuted such that the above holds and that is fine (i.e. it is not necessary that the order of <code>lookupTable</code> is equivalent to the order of first appearance in <code>dataSet</code>).</p>

<p><strong>Slow Solution:</strong></p>

<p>I currently have the following slow solution</p>

<pre><code>def indexDataSet(dataSet):
    """Returns the indexed dataSet and a lookup table
       Input:
           dataSet         : A length n numpy array to be indexed
       Output:
           indexed_dataSet : A length n numpy array containing values in {0, len(set(dataSet))-1}
           lookupTable     : A lookup table such that lookupTable[indexed_Dataset] = dataSet"""
    labels = set(dataSet)
    lookupTable = np.empty(len(labels), dtype='U21')
    indexed_dataSet = np.zeros(dataSet.size, dtype='int')
    count = -1
    for label in labels:
        count += 1
        indexed_dataSet[np.where(dataSet == label)] = count
        lookupTable[count] = label

    return indexed_dataSet, lookupTable
</code></pre>

<p>Is there a quicker way to do this? I feel like I am not using numpy to its full potential here.</p>