在数据帧连接时保留分类dtype

时间:2017-08-11 16:01:30

标签: python pandas dataframe

我有两个具有相同列名和dtypes的数据帧,类似于以下内容:

const token = localStorage.getItem('app-token');

export function request(config) {
   const { url, ...others } = config;

   return fetch(url, {
     ...others,
     credentials: 'include',
     headers: {
       'Authorization': `Bearer ${token}`
     },
   });
}

每个数据框中的类别都不相同。

正常结束时,大熊猫输出:

A             object
B             category
C             category

根据the documentation的预期行为。

但是,我希望保留分类并希望将类别结合起来,所以我在数据框中的列中尝试了union_categoricals,它们都是分类的。 A object B object C object cdf是我的两个数据框架。

df

这仍然没有为我提供分类输出。

3 个答案:

答案 0 :(得分:5)

我不认为这在文档中是完全明显的,但您可以执行以下操作。这是一些示例数据:

df1=pd.DataFrame({'x':pd.Categorical(['dog','cat'])})
df2=pd.DataFrame({'x':pd.Categorical(['cat','rat'])})

使用union_categoricals1获取一致的类别accros数据帧。如果您需要说服自己这样做,请尝试df.x.cat.codes

from pandas.api.types import union_categoricals

uc = union_categoricals([df1.x,df2.x])
df1.x = pd.Categorical( df1.x, categories=uc.categories )
df2.x = pd.Categorical( df2.x, categories=uc.categories )

连接并验证dtype是否分类。

df3 = pd.concat([df1,df2])

df3.x.dtypes
category

正如@ C8H10N4O2建议的那样,你也可以在连接后将对象强制转换回分类。老实说,对于较小的数据集,我认为这是最好的方法,因为它更简单。但对于较大的数据帧,使用union_categoricals应该可以提高内存效率。

答案 1 :(得分:2)

为补充JohnE的答案,以下函数通过将所有输入数据帧上存在的所有类别列转换为union_categoricals来完成工作:

def concatenate(dfs):
    """Concatenate while preserving categorical columns.

    NB: We change the categories in-place for the input dataframes"""
    from pandas.api.types import union_categoricals
    import pandas as pd
    # Iterate on categorical columns common to all dfs
    for col in set.intersection(
        *[
            set(df.select_dtypes(include='category').columns)
            for df in dfs
        ]
    ):
        # Generate the union category across dfs for this column
        uc = union_categoricals([df[col] for df in dfs])
        # Change to union category for all dataframes
        for df in dfs:
            df[col] = pd.Categorical( df[col], categories=uc.categories )
    return pd.concat(dfs)

请注意类别在输入列表中已更改:

df1=pd.DataFrame({'a': [1, 2],
                  'x':pd.Categorical(['dog','cat']),
                  'y': pd.Categorical(['banana', 'bread'])})
df2=pd.DataFrame({'x':pd.Categorical(['rat']),
                  'y': pd.Categorical(['apple'])})

concatenate([df1, df2]).dtypes

答案 2 :(得分:0)

JohnE的回答很有帮助,但在pandas 0.19.2中,union_categoricals只能按如下方式导入: from pandas.types.concat import union_categoricals