在Pandas数据框中转换分类数据


102

我有一个带有这种类型的数据的数据框(列太多):

col1        int64
col2        int64
col3        category
col4        category
col5        category

列看起来像这样:

Name: col3, dtype: category
Categories (8, object): [B, C, E, G, H, N, S, W]

我想像这样将列中的所有值转换为整数:

[1, 2, 3, 4, 5, 6, 7, 8]

我通过以下方法解决了这一问题:

dataframe['c'] = pandas.Categorical.from_array(dataframe.col3).codes

现在,我的数据框中有两列-旧列col3和新c列,需要删除旧列。

那是不好的做法。它是可行的,但是在我的数据框中有很多列,我不想手动进行。

pythonic如何巧妙地实现呢?

Answers:


163

首先,要将“分类”列转换为其数字代码,可以使用以下命令更轻松地做到这一点dataframe['c'].cat.codes
此外,可以使用来自动选择数据框中具有特定dtype的所有列select_dtypes。这样,您可以将上述操作应用于多个自动选择的列。

首先制作一个示例数据框:

In [75]: df = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})

In [76]: df['col2'] = df['col2'].astype('category')

In [77]: df['col3'] = df['col3'].astype('category')

In [78]: df.dtypes
Out[78]:
col1       int64
col2    category
col3    category
dtype: object

然后通过使用select_dtypes选择列,然后将其应用于.cat.codes这些列中的每一个,您可以获得以下结果:

In [80]: cat_columns = df.select_dtypes(['category']).columns

In [81]: cat_columns
Out[81]: Index([u'col2', u'col3'], dtype='object')

In [83]: df[cat_columns] = df[cat_columns].apply(lambda x: x.cat.codes)

In [84]: df
Out[84]:
   col1  col2  col3
0     1     0     0
1     2     1     1
2     3     2     0
3     4     0     1
4     5     1     1

14
有没有一种简单的方法来获取类别代码和类别字符串值之间的映射?
艾伦·鲁恩

5
您可以使用: df['col2'].cat.categories例如。
ogrisel

13
指出任何相关人士,这将NaN唯一地映射到-1
quietContest

2
爱2班轮;)
Jose A

注意,如果分类是有序的(序数),则返回的数字代码cat.codes可能不是您在系列中看到的数字!
paulperry

27

这对我有用:

pandas.factorize( ['B', 'C', 'D', 'B'] )[0]

输出:

[0, 1, 2, 0]

20

如果您只关心增加一列并在以后将其删除,则只需在第一处使用新列即可。

dataframe = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})
dataframe.col3 = pd.Categorical.from_array(dataframe.col3).codes

大功告成 现在Categorical.from_array已弃用,请Categorical直接使用

dataframe.col3 = pd.Categorical(dataframe.col3).codes

如果您还需要从索引到标签的映射,那么还有更好的方法

dataframe.col3, mapping_index = pd.Series(dataframe.col3).factorize()

检查下面

print(dataframe)
print(mapping_index.get_loc("c"))

11

这里需要转换多列。因此,我使用的一种方法是..

for col_name in df.columns:
    if(df[col_name].dtype == 'object'):
        df[col_name]= df[col_name].astype('category')
        df[col_name] = df[col_name].cat.codes

这会将所有字符串/对象类型列转换为类别。然后将代码应用于每种类别。


3

为了转换数据集数据的C列中的分类数据,我们需要执行以下操作:

from sklearn.preprocessing import LabelEncoder 
labelencoder= LabelEncoder() #initializing an object of class LabelEncoder
data['C'] = labelencoder.fit_transform(data['C']) #fitting and transforming the desired categorical column.

1

@ Quickbeam2k1,请参见下文-

dataset=pd.read_csv('Data2.csv')
np.set_printoptions(threshold=np.nan)
X = dataset.iloc[:,:].values

使用sklearn 在此处输入图片说明

from sklearn.preprocessing import LabelEncoder
labelencoder_X=LabelEncoder()
X[:,0] = labelencoder_X.fit_transform(X[:,0])

3
您为什么不更正先前的答案?出人意料的是,您现在使用fit_transform而不是transform_fit并且更正了labelencoder定义。你为什么用iloc[:,:]?这没用。图片背后的原因是什么?如果您想证明我,而@theGtknerd感到您失败了。
Quickbeam2k1

1

我要做的是,我 replace重视。

像这样-

df['col'].replace(to_replace=['category_1', 'category_2', 'category_3'], value=[1, 2, 3], inplace=True)

这样,如果该col列具有分类值,则将它们替换为数值。


0

对于特定的列,如果您不关心顺序,请使用此

df['col1_num'] = df['col1'].apply(lambda x: np.where(df['col1'].unique()==x)[0][0])

如果您关心订购,请将其指定为列表并使用它

df['col1_num'] = df['col1'].apply(lambda x: ['first', 'second', 'third'].index(x))
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.