2010-07-03 9 views
11

Próbuję przekonwertować tablicę zmiennych kategorialnych na tablicę całkowitą zmiennych jakościowych.numpy konwertuj kategoryczne tablice ciągów na tablicę całkowitą

Przykł.

import numpy as np 
a = np.array(['a', 'b', 'c', 'a', 'b', 'c']) 
print a.dtype 
>>> |S1 

b = np.unique(a) 
print b 
>>> ['a' 'b' 'c'] 

c = a.desired_function(b) 
print c, c.dtype 
>>> [1,2,3,1,2,3] int32 

Zdaję sobie sprawę, że można to zrobić za pomocą pętli, ale wyobrażam sobie, że jest łatwiejszy sposób. Dzięki.

Odpowiedz

2

To jest hack ... ale czy to pomaga?

In [72]: c=(a.view(np.ubyte)-96).astype('int32') 

In [73]: print(c,c.dtype) 
(array([1, 2, 3, 1, 2, 3]), dtype('int32')) 
+9

poważnie chcesz dodać zastrzeżenie, że to działa tylko na długości 1 strun. – smci

17

Jednym ze sposobów jest wykorzystanie funkcji categorical od scikits.statsmodels. Na przykład:

In [60]: from scikits.statsmodels.tools import categorical 

In [61]: a = np.array(['a', 'b', 'c', 'a', 'b', 'c']) 

In [62]: b = categorical(a, drop=True) 

In [63]: b.argmax(1) 
Out[63]: array([0, 1, 2, 0, 1, 2]) 

Wartość zwracana z categorical (b) jest rzeczywiście matryca projekt, stąd wywołanie argmax powyżej dostać to blisko do żądanego formatu.

In [64]: b 
Out[64]: 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.], 
     [ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.]]) 
+0

Schludny i sprytny. Dzięki. – unutbu

24

np.unique ma pewne opcjonalne powraca

return_inverse daje całkowitą kodowania, które wykorzystują często

>>> b, c = np.unique(a, return_inverse=True) 
>>> b 
array(['a', 'b', 'c'], 
     dtype='|S1') 
>>> c 
array([0, 1, 2, 0, 1, 2]) 
>>> c+1 
array([1, 2, 3, 1, 2, 3]) 

może być wykorzystane do odtworzenia oryginalnego tablicę z unikalnych

>>> b[c] 
array(['a', 'b', 'c', 'a', 'b', 'c'], 
     dtype='|S1') 
>>> (b[c] == a).all() 
True 
19

... lat później ....

Dla kompletności (bo to nie jest wymienione w odpowiedziach) oraz powody osobiste (I zawsze mieć pandas importowany w moich modułów ale niekoniecznie sklearn), jest to również dość proste z pandas.get_dummies()

import numpy as np 
import pandas 

In [1]: a = np.array(['a', 'b', 'c', 'a', 'b', 'c']) 

In [2]: b = pandas.get_dummies(a) 

In [3]: b 
Out[3]: 
     a b c 
    0 1 0 0 
    1 0 1 0 
    2 0 0 1 
    3 1 0 0 
    4 0 1 0 
    5 0 0 1 

In [3]: b.values.argmax(1) 
Out[4]: array([0, 1, 2, 0, 1, 2]) 
+0

Dzięki. W końcu znalazłem odpowiedź, której szukam. – SeeTheC

1

Innym sposobem jest użycie Pandy factorize mapować elementy do numeru:

In [1]: import numpy as np 
In [2]: import pandas as pd 
In [3]: a = np.array(['a', 'b', 'c', 'a', 'b', 'c']) 
In [4]: a_enc = pd.factorize(a) 
In [5]: a_enc[0] 
Out[5]: array([0, 1, 2, 0, 1, 2]) 
In [6]: a_enc[1] 
Out[6]: array(['a', 'b', 'c'], dtype=object) 
0

... kilka lat przechodzą ...

myślałem, że dostarczenie czystego roztworu Pythona dla kompletności:

def count_unique(a): 
    def counter(item, c=[0], items={}): 
     if item not in items: 
      items[item] = c[0] 
      c[0] += 1 
     return items[item] 
    return map(counter, a) 

a = [0, 2, 6, 0, 2] 
print count_unique(a) 
>> [0, 1, 2, 0, 1] 
Powiązane problemy