2016-04-17 23 views
5

Problema:Mappare una serie NumPy di ​​stringhe di numeri interi

Dato un array di dati stringa

dataSet = np.array(['kevin', 'greg', 'george', 'kevin'], dtype='U21'), 

Vorrei una funzione che restituisce il set di dati indicizzato

indexed_dataSet = np.array([0, 1, 2, 0], dtype='int') 

e una tabella di ricerca

lookupTable = np.array(['kevin', 'greg', 'george'], dtype='U21') 

tale che

(lookupTable[indexed_dataSet] == dataSet).all() 

è vero. Si noti che i valori indexed_dataSet e lookupTable possono essere entrambi permutati in modo tale che il precedente sia valido e che sia corretto (ovvero non è necessario che l'ordine di lookupTable sia equivalente all'ordine di prima apparizione in dataSet).

lenta Soluzione:

Al momento ho la seguente soluzione lenta

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 

C'è un modo più rapido per fare questo? Mi sento come se non stia usando Numpy al suo pieno potenziale qui.

+0

Sto cercando una soluzione Python e Numpy pura – rwolst

risposta

7

È possibile utilizzare np.unique con la return_inverse argomento:

>>> lookupTable, indexed_dataSet = np.unique(dataSet, return_inverse=True) 
>>> lookupTable 
array(['george', 'greg', 'kevin'], 
     dtype='<U21') 
>>> indexed_dataSet 
array([2, 1, 0, 2]) 

Se si desidera, è possibile ricostruire la matrice originale da queste due matrici:

>>> lookupTable[indexed_dataSet] 
array(['kevin', 'greg', 'george', 'kevin'], 
     dtype='<U21') 

Se si utilizzano i panda , lookupTable, indexed_dataSet = pd.factorize(dataSet) otterrà la stessa cosa (e potenzialmente sarà più efficiente per i grandi array).

1

np.searchsorted fa il trucco:

dataSet = np.array(['kevin', 'greg', 'george', 'kevin'], dtype='U21'), 
lut = np.sort(np.unique(dataSet)) # [u'george', u'greg', u'kevin'] 
ind = np.searchsorted(lut,dataSet) # array([[2, 1, 0, 2]]) 
Problemi correlati