2016-11-04 2 views
1

I den Code Balg bin mit einem Datensatz zu kodieren:Nans auf pd.factorize Rückgabeobjekt

foo= pd.DataFrame({ 
        'Col1' : ['B', 'A', 'B', 'C', 'B', 'A', 'C'], 
        'Val' : np.random.randn(7) 
        }) 
r=pd.factorize(foo['Col1'], sort=True) 
foo['Col1'] = r[0] 

, die das folgende richtige Ergebnis (vor \ after) erzeugt:

Col1  Val   Col1  Val 
    B 0.094336    1 0.094336 
    A -0.422168    0 -0.422168 
    B -0.750304    1 -0.750304 
    C 1.910625    2 1.910625 
    B 0.921890    1 0.921890 
    A 0.422612    0 0.422612 
    C -1.130780    2 -1.130780 


print r 
(array([1, 0, 1, 2, 1, 0, 2]), Index([u'A', u'B', u'C'], dtype='object')) 

und (wegen der „Art“) ich kann auch eine Abbildungsfunktion zwischen Schlüssel \ Wert aufbauen, indem Sie - das ist mein Ziel:

zip(np.unique(r[0]), r[1]) 
[(0, 'A'), (1, 'B'), (2, 'C')] # A became 0; B became 1 and so on... 

mein Problem, das ich s, wenn ich nans auf den Datensatz und sie bekommen -1 (das ist genau das, was ich will - es hat -1 sein):

foo= pd.DataFrame({ 
        'Col1' : ['B', 'A', 'B', 'C', 'B', 'A', np.nan], 
        'Val' : np.random.randn(7) 
        }) 

r=pd.factorize(foo['Col1'], sort=True) 
foo['Col1'] = r[0] 


Col1  Val   Col1  Val 
    B 1.397748   1 1.397748 
    A -1.011483   0 -1.011483 
    B 0.679650   1 0.679650 
    C 0.861900   2 0.861900 
    B -0.430241   1 -0.430241 
    A 1.472984   0 1.472984 
NaN 0.549857   -1 0.549857 

aber die pd.factorize kehrt nicht die „nan“ auf der Index:

print r[1] 
Index([u'A', u'B', u'C'], dtype='object') 

und jetzt meine Mapping-Funktion nicht funktioniert:

zip(np.unique(r[0]), r[1]) 
Out[148]: [(-1, 'A'), (0, 'B'), (1, 'C')] 

Jede Art und Weise die pd.factorize Funktion zurückgeben den nan auf seinen Index Objekt zu machen?

Dank

Antwort

1

Wenn Sie, dass der einzige Grund für eine -1 in r[0] ist np.nan in Ihrem Datensatz garantieren können, dann können Sie die gewünschte Abbildung mit der folgenden Funktion erhalten:

def get_mapping(r): 
    if -1 in r[0]: 
     return zip(np.unique(r[0]), r[1].insert(0, np.nan)) 
    else: 
     return zip(np.unique(r[0]), r[1]) 
2

Da die Spalte enthält dtypes von float + str in es als Ergebnis von Nans vorhanden, pd.factorize enthält die fehlenden Werte nach dem Zuweisen eines Werts von -1 (Standard).

Eine Alternative wäre die eindeutigen Werte in der Serie zu berechnen und sie später in categorical dtype umwandeln, die auch einen Wert von -1 für Nans ordnet durch codes Attribut ist.

Demo:

ser = pd.Series(foo['Col1'].unique(), dtype='category') 
ser 
Out[125]: 
0  B 
1  A 
2  C 
3 NaN 
dtype: category 
Categories (3, object): [A, B, C] 

print(list(zip(ser, ser.cat.codes))) 
#[('B', 1), ('A', 0), ('C', 2), (nan, -1)]