2017-01-21 7 views
3

Angenommen, ich habe:pd.Categorical.from_codes mit fehlenden Werten

df = pd.DataFrame({'gender': np.random.choice([1, 2], 10), 'height': np.random.randint(150, 210, 10)}) 

Ich möchte die gender-Spalte kategorisch machen. Wenn ich versuche:

df['gender'] = pd.Categorical.from_codes(df['gender'], ['female', 'male']) 

wird es fehlschlagen.

Ich kann Pad die Kategorien

df['gender'] = pd.Categorical.from_codes(df['gender'], ['N/A', 'female', 'male']) 

Aber dann wird 'N/A' in einigen Verfahren zurückgegeben:

In [67]: df['gender'].value_counts() 
Out[67]: 
female 5 
male  5 
N/A  0 
Name: gender, dtype: int64 

Ich dachte über None als padding-Wert. Es funktioniert wie in den value_counts sollte jedoch ich eine Warnung erhalten:

opt/anaconda3/bin/ipython:1: FutureWarning: 
Setting NaNs in `categories` is deprecated and will be removed in a future version of pandas. 
    #!/opt/anaconda3/bin/python 

einen besseren Weg, dies zu tun? Gibt es auch eine Möglichkeit, eine Zuordnung von Code zu Kategorie explizit anzugeben?

+0

OK, fand über 'df out [ 'Geschlecht'] cat.remove_unused_categories (Inplace = True)'.. Ich suche immer noch nach einem besseren Weg. – lazy1

Antwort

0

Der Fehler, den Sie von pd.Categorical.from_codes(df['gender'], ['female', 'male']) erhalten, sollte Sie warnen, dass Ihr codes 0 indiziert werden muss.

So können Sie es einfach mit Ihrer DataFrame-Deklaration machen.

df = pd.DataFrame({'gender': np.random.choice([0, 1], 10), 'height': np.random.randint(150, 210, 10)}) 
+0

Danke, aber in meinem Fall sind die Daten von außerhalb der Quelle und ich habe keine Kontrolle über die "Geschlecht" -Werte. – lazy1

1

können Sie rename_categories() Methode verwenden:

Demo:

In [33]: df 
Out[33]: 
    gender height 
0  1  203 
1  2  169 
2  2  181 
3  1  172 
4  2  174 
5  1  166 
6  2  187 
7  2  200 
8  1  208 
9  1  201 

In [34]: df['gender'] = df['gender'].astype('category').cat.rename_categories(['male','feemale']) 

In [35]: df 
Out[35]: 
    gender height 
0  male  203 
1 feemale  169 
2 feemale  181 
3  male  172 
4 feemale  174 
5  male  166 
6 feemale  187 
7 feemale  200 
8  male  208 
9  male  201 

In [36]: df.dtypes 
Out[36]: 
gender category 
height  int32 
dtype: object 
1

die neuen Kategorien zuweisen, direkt an es ist .categories Attribut und es würde dann auf diese Werte umbenannt werden:

df['gender'] = df['gender'].astype('category') 
df['gender'].cat.categories = ['female', 'male'] 

df['gender'].value_counts() 
Out[23]: 
female 7 
male  3 
Name: gender, dtype: int64 

df.dtypes 
Out[24]: 
gender category 
height  int32 
dtype: object 

Wenn Sie einen Mapper dict von Code und die jeweilige Kategorie wollen, dann:

old = df['gender'].cat.categories 
new = ['female', 'male'] 

dict(zip(old, new)) 
Out[28]: 
{1: 'female', 2: 'male'} 
+1

Danke. Das Problem, das ich damit sehe (und auch meine Lösung) ist, dass nicht "df ['gender']. Cat.codes' in' [0, 1] 'und nicht' [1, 2] 'wie das Original ist. Ich werde als gelöst markieren, da ich nicht denke, dass ich etwas besseres bekomme. – lazy1

Verwandte Themen