转换pandas数据帧中的分类数据

Gil*_*tam 81 python pandas

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

col1        int64
col2        int64
col3        category
col4        category
col5        category
Run Code Online (Sandbox Code Playgroud)

列似乎是这样的:

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

我想将列中的所有值转换为整数,如下所示:

[1, 2, 3, 4, 5, 6, 7, 8]
Run Code Online (Sandbox Code Playgroud)

我通过这个解决了一个问题:

dataframe['c'] = pandas.Categorical.from_array(dataframe.col3).codes
Run Code Online (Sandbox Code Playgroud)

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

这是不好的做法.这是工作,但在我的数据框架中有很多列,我不想手动完成.

这个pythonic怎么这么巧妙?

jor*_*ris 137

首先,要将Categorical列转换为其数字代码,您可以使用以下方法更轻松地执行此操作: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
Run Code Online (Sandbox Code Playgroud)

然后通过使用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
Run Code Online (Sandbox Code Playgroud)

  • 有没有一种简单的方法可以获得类别代码和类别字符串值之间的映射? (13认同)
  • 指出任何人都担心这会将"NaN"唯一映射到"-1" (11认同)
  • 你可以使用:`df ['col2'].cat.categories`. (4认同)
  • 爱2班轮;) (2认同)
  • 请注意,如果分类是有序的(序数),那么“cat.codes”返回的数字代码可能不是您在系列中看到的代码! (2认同)

sco*_*tle 19

这对我有用:

pandas.factorize( ['B', 'C', 'D', 'B'] )[0]
Run Code Online (Sandbox Code Playgroud)

输出:

[0, 1, 2, 0]
Run Code Online (Sandbox Code Playgroud)

  • 被低估的答案 (6认同)
  • 我同意,这是一个非常好的和有效的答案 (4认同)
  • 最佳答案,恕我直言 (4认同)
  • 虽然这解决了问题,但出于性能原因,您应该更喜欢访问器“pd.Series.cat.codes”而不是“pd.factorize”。在内部,分类已经是一个索引列表,通过“.cat.codes”提取它需要“O(0)”时间,而通过“pd.factorize”(重新)分解需要“O(n)”时间( [目前](https://github.com/pandas-dev/pandas/blob/5d17d73be969a7d004a7e1035afbf811a8fbf18a/pandas/core/algorithms.py#L634-L812)没有分类的快速路径)。 (3认同)
  • 太好了,比接受的答案简单得多 (2认同)

Abh*_*hek 18

如果你只关心你制作一个额外的列并在以后删除它,那么只需在第一个地方使用一个新列.

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

你完成了.现在Categorical.from_array已弃用,请Categorical直接使用

dataframe.col3 = pd.Categorical(dataframe.col3).codes
Run Code Online (Sandbox Code Playgroud)

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

dataframe.col3, mapping_index = pd.Series(dataframe.col3).factorize()
Run Code Online (Sandbox Code Playgroud)

检查下面

print(dataframe)
print(mapping_index.get_loc("c"))
Run Code Online (Sandbox Code Playgroud)


sha*_*hak 8

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

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
Run Code Online (Sandbox Code Playgroud)

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


tru*_*uth 8

我所做的是,我replace重视。

像这样-

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

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


sau*_*i23 8

要将 Dataframe 中的所有列转换为数值数据:

df2 = df2.apply(lambda x: pd.factorize(x)[0])
Run Code Online (Sandbox Code Playgroud)


Fat*_*jad 5

为了转换数据集data 的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.
Run Code Online (Sandbox Code Playgroud)


Ham*_*mza 5

这里的答案似乎已经过时了。Pandas 现在有一个factorize()功能,您可以创建类别:

df.col.factorize() 
Run Code Online (Sandbox Code Playgroud)

函数签名:

pandas.factorize(values, sort=False, na_sentinel=- 1, size_hint=None)
Run Code Online (Sandbox Code Playgroud)