熊猫:将类别转换为数字


82

假设我有一个包含以下国家/地区的数据框:

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

我知道有一个pd.get_dummies函数可以将国家/地区转换为“一次性编码”。但是,我希望将它们转换为索引,以便获取cc_index = [1,2,1,3]

我假设有一种比使用get_dummies和numpy where子句更快的方法,如下所示:

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

这在R中使用“因素”更容易做到,所以我希望熊猫也有类似的东西。


2
你的意思是cc_index = [0,1,0,2]
juanpa.arrivillaga

1
当然,忘记了python 0索引
sachinruk

DataFrame中的分类系列或列可能会有所帮助。
min2bro

Answers:


143

首先,更改列的类型:

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

现在,数据看起来很相似,但是是按类别存储的。要捕获类别代码:

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

现在您有了:

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

如果您不想修改DataFrame,而只需获取代码:

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

或使用分类列作为索引:

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

2
通话df.cc.cat.codes似乎已更改为df.cc.codes
Andreas Storvik Strauman

请注意,如果缺少值,它们将被编码为-1。如果要避免这种情况,可以先转换为字符串:df.cc.astype('str')。astype('category')。cat.codes
Guy

23

如果只希望将序列转换为整数标识符,可以使用pd.factorize

请注意,与相比pd.Categorical,此解决方案不会按字母顺序排序。因此,将分配第一个国家0。如果希望从开始1,可以添加一个常量:

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

如果您希望按字母顺序排序,请指定sort=True

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

11

如果您使用的是sklearn库,则可以使用LabelEncoder。像一样pd.Categorical,输入字符串在编码之前按字母顺序排序。

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

尝试此操作,将其转换为基于频率的数字(高频-高数字):

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

1

将任何列更改为Numbers。它不会创建新列,而只是将数值替换为数值数据。

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


0

单行代码:

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

如果您有list_of_columns

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

此外,如果要保留您的NaN值,可以应用替换:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes).replace(-1,np.nan)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.