Python 将分类列添加到数据框,并将类别与现有分类列相匹配

Python 将分类列添加到数据框,并将类别与现有分类列相匹配,python,pandas,Python,Pandas,我有两个数据帧,其中包含逻辑上相互关联的分类列,并且包含相同数量的类别:df1中的类别1、df2中的类别1、df1中的类别2、df2中的类别2,等等。。数据帧的长度不同,而且行没有排序,因此我不能简单地对它们进行重新排序和连接 我想将df2的分类变量添加到df1中,以便两个分类列的类别都匹配 下面是一个例子: import pandas as pd foo = pd.Categorical(values=[0,1,2,3],categories=[0,1,2,3],ordered=True)

我有两个数据帧,其中包含逻辑上相互关联的分类列,并且包含相同数量的类别:df1中的类别1、df2中的类别1、df1中的类别2、df2中的类别2,等等。。数据帧的长度不同,而且行没有排序,因此我不能简单地对它们进行重新排序和连接

我想将df2的分类变量添加到df1中,以便两个分类列的类别都匹配

下面是一个例子:

import pandas as pd

foo = pd.Categorical(values=[0,1,2,3],categories=[0,1,2,3],ordered=True)
bar = pd.Categorical(values=['b','c','b','a','d','a'],categories=['a','b','c','d'],ordered=True)

df_1 = pd.DataFrame({'foo':foo})
df_2 = pd.DataFrame({'bar':bar})
我想得到:

  foo bar
0   0   a
1   1   b
2   2   c
3   3   d

编辑

当两个数据帧包含其他列时,该解决方案也应起作用,例如:

import pandas as pd

foo_1 = pd.Categorical(values=[0,1,2,3],categories=[0,1,2,3],ordered=True)
foo_2 = pd.Series(['x','y','z','x'])

bar_1 = pd.Categorical(values=['b','c','b','a','d','a'],categories=['a','b','c','d'],ordered=True)
bar_2 = pd.Series([0.1,0.2,0.3,0.3,0.5,0.6])

df_1 = pd.DataFrame({'foo_1':foo_1,'foo_2':foo_2})
df_2 = pd.DataFrame({'bar_1':bar_1,'bar_2':bar_2})
使用序列映射时,对齐方式是使用序列索引,这就是为什么df_1中的前四行映射到df_2中的前四个值。相反,您需要确保在分类代码上对齐

Series.cat.categories将按顺序列出类别。您可以使用enumerate从第二个分类列创建一个简单的字典,并映射第一个分类列的代码

d = dict(enumerate(df_2['bar'].cat.categories))
df_1['bar'] = df_1['foo'].cat.codes.map(d)

#  foo bar
#0   0   a
#1   1   b
#2   2   c
#3   3   d

您可以将索引带到变量并合并两个数据集,如下所示:

df_1.merge(df_2.reset_index(), left_on=['foo'], right_on=['index'], how='left')
结果:

    foo index   bar
0   0   0       b
1   1   1       c
2   2   2       b
3   3   3       a


是的,两个分类变量都是有序的,并且类别相互对应。
df_1.merge(df_2.reset_index(), left_on=['foo'], right_on=['index'], how='left')
    foo index   bar
0   0   0       b
1   1   1       c
2   2   2       b
3   3   3       a