2016-04-17 16 views
5

Problem:mapie tablicę NumPy ciągów liczb całkowitych

Biorąc pod tablicą danych łańcuchowych

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

Chciałbym funkcję zwracającą indeksowanego zbioru danych

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

i tabela odnośników

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

takie, że

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

jest prawdą. Zauważ, że wartości indexed_dataSet i mogą być zarówno permutowane tak, że powyższe wartości utrzymują się i które są drobne (tj. Nie jest konieczne, aby kolejność pierwszego pojawienia się w dataSet) była równa.

Powolne Rozwiązanie:

Obecnie mam następujący powolny rozwiązanie

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 

Czy istnieje szybszy sposób to zrobić? Czuję, że nie używam tu numpy do pełnego potencjału.

+0

Szukam czystego rozwiązania Python i Numpy – rwolst

Odpowiedz

7

Można użyć np.unique z return_inverse argumentu:

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

Jeśli chcesz, możesz odtworzyć oryginalną tablicę z tych dwóch tablic:

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

Jeśli używasz pand , lookupTable, indexed_dataSet = pd.factorize(dataSet) osiągnie to samo (i potencjalnie będzie bardziej wydajne w przypadku dużych tablic).

1

np.searchsorted załatwia sprawę:

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]]) 
Powiązane problemy