Pandalar: kategorileri sayılara dönüştürme


86

Aşağıdaki gibi giden ülkeleri içeren bir veri çerçevem ​​olduğunu varsayalım:

cc | temp
US | 37.0
CA | 12.0
US | 35.0
AU | 20.0

Ülkeleri 'tek sıcak kodlamalara' dönüştürmek için bir pd.get_dummies işlevi olduğunu biliyorum. Ancak, bunun yerine alacağım şekilde onları endekslere dönüştürmek istiyorum cc_index = [1,2,1,3].

Aşağıda gösterildiği gibi bir numpy where cümlesiyle birlikte get_dummies kullanmaktan daha hızlı bir yol olduğunu varsayıyorum:

[np.where(x) for x in df.cc.get_dummies().values]

Bunu R'de 'faktörleri' kullanarak yapmak biraz daha kolaydır, bu yüzden pandalarda da benzer bir şey olduğunu umuyorum.


2
Şunu musunuz cc_index = [0,1,0,2]?
juanpa.arrivillaga

1
elbette, python 0 endeksini unuttum
sachinruk

Bir DataFrame'deki Kategorik Seriler veya sütunlar yardımcı olabilir.
min2bro

Yanıtlar:


150

İlk olarak, sütunun türünü değiştirin:

df.cc = pd.Categorical(df.cc)

Şimdi veriler benzer görünüyor ancak kategorik olarak saklanıyor. Kategori kodlarını yakalamak için:

df['code'] = df.cc.cat.codes

Şimdi sahipsin:

   cc  temp  code
0  US  37.0     2
1  CA  12.0     1
2  US  35.0     2
3  AU  20.0     0

DataFrame'inizi değiştirmek istemiyor ancak sadece kodları alıyorsanız:

df.cc.astype('category').cat.codes

Veya kategorik sütunu bir dizin olarak kullanın:

df2 = pd.DataFrame(df.temp)
df2.index = pd.CategoricalIndex(df.cc)

5
Çağrı df.cc.cat.codessadece değişmiş gibi görünüyor df.cc.codes?
Andreas Storvik Strauman

1
Eksik değerleriniz varsa bunların -1 olarak kodlanacağını unutmayın. Bu vakayı ele almaktan kaçınmak istiyorsanız, önce dizeye çevirebilirsiniz: df.cc.astype ('str']. Astype ('category'). Cat.codes
Guy s

NaNGibi görünüyor -1?
ahbon

25

Sadece serinizi tamsayı tanımlayıcılara dönüştürmek istiyorsanız kullanabilirsiniz pd.factorize.

Bu çözümün aksine pd.Categorical, alfabetik olarak sıralanmayacağını unutmayın. Böylece ilk ülke atanacak 0. Başlamak isterseniz 1bir sabit ekleyebilirsiniz:

df['code'] = pd.factorize(df['cc'])[0] + 1

print(df)

   cc  temp  code
0  US  37.0     1
1  CA  12.0     2
2  US  35.0     1
3  AU  20.0     3

Alfabetik olarak sıralamak isterseniz şunları belirtin sort=True:

df['code'] = pd.factorize(df['cc'], sort=True)[0] + 1 

14

sklearnKütüphaneyi kullanıyorsanız kullanabilirsiniz LabelEncoder. Benzer şekilde pd.Categorical, giriş dizeleri kodlamadan önce alfabetik olarak sıralanır.

from sklearn.preprocessing import LabelEncoder

LE = LabelEncoder()
df['code'] = LE.fit_transform(df['cc'])

print(df)

   cc  temp  code
0  US  37.0     2
1  CA  12.0     1
2  US  35.0     2
3  AU  20.0     0

2

Bunu deneyin, frekansa göre sayıya dönüştürün (yüksek frekans - yüksek sayı):

labels = df[col].value_counts(ascending=True).index.tolist()
codes = range(1,len(labels)+1)
df[col].replace(labels,codes,inplace=True)

1

Herhangi bir sütunu Numbers olarak değiştirecektir. Yeni bir sütun oluşturmayacak, sadece değerleri sayısal verilerle değiştirecektir.

def characters_to_numb(*args): for arg in args: df[arg] = pd.Categorical(df[arg]) df[arg] = df[arg].cat.codes return df


0

Tek satırlık kod:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes)

Bu, aşağıdaki durumlarda da işe yarar list_of_columns:

df[list_of_columns] = df[list_of_columns].apply(lambda col:pd.Categorical(col).codes)

Ayrıca, NaNdeğerlerinizi korumak istiyorsanız, bir değiştirme uygulayabilirsiniz:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes).replace(-1,np.nan)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.