Pandas将所有对象列转换为分类。

10

我想要一个优雅的函数来将pandas数据框中的所有对象列转换为类别(categories)。

df[x] = df[x].astype("category") 执行类型转换。 df.select_dtypes(include=['object']) 可以子选择所有类别(categories)列。但是这会导致其他列的丢失/需要手动合并。是否有一种“直接就地”或不需要手动类型转换的解决方案?

编辑

我正在寻找类似于http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.convert_objects.html 的东西,用于将数据转换为类别(categorical)数据。

4个回答

11

使用applypd.Series.astype,并指定dtype='category'

考虑一个pd.DataFrame df

df = pd.DataFrame(dict(
        A=[1, 2, 3, 4],
        B=list('abcd'),
        C=[2, 3, 4, 5],
        D=list('defg')
    ))
df

输入图片描述

df.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
A    4 non-null int64
B    4 non-null object
C    4 non-null int64
D    4 non-null object
dtypes: int64(2), object(2)
memory usage: 200.0+ bytes

使用 select_dtypes 来包含所有的 'object' 类型并将其转换后,再与一个排除它们的 select_dtypes 重新组合。

df = pd.concat([
        df.select_dtypes([], ['object']),
        df.select_dtypes(['object']).apply(pd.Series.astype, dtype='category')
        ], axis=1).reindex_axis(df.columns, axis=1)

df.info()

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 4 entries, 0 to 3
Data columns (total 4 columns):
A    4 non-null int64
B    4 non-null category
C    4 non-null int64
D    4 non-null category
dtypes: category(2), int64(2)
memory usage: 208.0 bytes

确实,这是一个很好的开始。但是我只想转换对象类型,而不是浮点数或整数,因为你的解决方案“强制”将任何东西都转换为类别。 - Georg Heiler
这个代码:df.select_dtypes(include=['object']).apply(pd.Series.astype, dtype='category').info() 部分有效,例如所有对象都被转换。但是随后需要手动合并数值列。如何才能避免这种情况,并且有选择性地直接更改数据类型? - Georg Heiler
也许有更高效的方法吗? - Benni

7
我认为这是更加优雅的方式:
df = pd.DataFrame(dict(
        A=[1, 2, 3, 4],
        B=list('abcd'),
        C=[2, 3, 4, 5],
        D=list('defg')
    ))

df.info()

df.loc[:, df.dtypes == 'object'] =\
    df.select_dtypes(['object'])\
    .apply(lambda x: x.astype('category'))

df.info()

2

0
通常类别的顺序具有意义,例如T恤尺码'S'、'M'、'L'、'XL'是有序类别(在SPSS中为序数)。如果您想从字符串创建有序类别,可以使用以下代码:
df = pd.concat([
        df.select_dtypes([], ['object']),
        df.select_dtypes(['object']).apply(pd.Categorical, ordered=True)
        ], axis=1).reindex(df.columns, axis=1)

在生成的DataFrame中,分类列可以按照与排序字符串相同的方式进行排序。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接