2016-04-17 8 views
5

Problem:Karte eine NumPy Array von Strings auf ganze Zahlen

ein Array von String-Daten Bei

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

ich eine Funktion möchte, dass die indizierte Dataset

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

zurückgibt und eine Nachschlagetabelle

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

so dass

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

wahr ist. Man beachte, dass die indexed_dataSet und lookupTable beide permutiert werden können, so dass das obige gilt, und das ist in Ordnung (d. H. Es ist nicht notwendig, dass die Reihenfolge von lookupTable der Reihenfolge des ersten Auftretens in dataSet entspricht).

Langsam Lösung:

Im Moment habe ich die folgende langsame Lösung

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 

Gibt es einen schnelleren Weg, dies zu tun? Ich habe das Gefühl, ich nutze hier nicht das volle Potenzial.

+0

Ich bin auf der Suche nach einer reinen Python und Numpy Lösung – rwolst

Antwort

7

Sie np.unique mit dem return_inverse Argument verwenden:

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

Wenn Sie möchten, können Sie Ihre ursprüngliche Array aus diesen beiden Arrays rekonstruieren:

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

Wenn Sie Pandas verwenden , lookupTable, indexed_dataSet = pd.factorize(dataSet) wird das gleiche erreichen (und möglicherweise für große Arrays effizienter sein).

1

np.searchsorted funktioniert der Trick:

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]]) 
Verwandte Themen