在公共索引上合并两个数据框(无需创建单独的行)

时间:2017-02-25 07:51:17

标签: python pandas dataframe merge

我是熊猫的新手并且已经玩了一下。我希望基于一个共同的索引,用户id来连接两个数据帧。但是,我想做更多一点。在第一个表(包含用户ID及其年龄)中,每个用户ID都是唯一的。在第二个表(包含用户ID及其课程,但未按用户ID排序)中,可能有多个相同的用户ID(因为用户可以使用多个课程,但每行只包含一个用户ID和一个课程)。数据集相当大,所以这不是我可以手动完成的。如果我想加入以便我仍然维护属性,结果表中的用户ID是唯一的,以便每行包含{用户ID,年龄,所有课程},我该怎么做。

例如,我可能会有类似

的内容
Table 1:             Table 2:
User Id Age          User Id  Coursework
1       18           1        Pre Calculus
2       17           2        Chemistry
3       18           3        English
4       16           2        Linear Algebra
                     1        World History
                     4        Multivariable Calculus
                     1        Psychology
                     3        Government
                     4        Physics (E&M)

我希望结果如下:

User Id Age  Coursework
1       18   Pre Calculus, World History, Psychology
2       17   Chemistry, Linear Algebra
3       18   English, Government
4       16   Multivariable Calculus, Physics (E&M)

我将如何以尽可能简单的方式进行此操作?它可能需要一种不同的方法,而不仅仅是合并和做一些事情。无论如何,这对于我使用大型数据集所做的事情非常有用。感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我首先转换(分组)第二个DF,然后将其与第一个DF合并:

In [11]: b.groupby('User_Id', as_index=False)[['Coursework']] \
          .agg(', '.join).merge(a, on='User_Id')
Out[11]:
   User_Id                               Coursework  Age
0        1  Pre Calculus, World History, Psychology   18
1        2                Chemistry, Linear Algebra   17
2        3                      English, Government   18
3        4    Multivariable Calculus, Physics (E&M)   16

数据:

In [12]: a
Out[12]:
   User_Id  Age
0        1   18
1        2   17
2        3   18
3        4   16

In [13]: b
Out[13]:
   User_Id              Coursework
0        1            Pre Calculus
1        2               Chemistry
2        3                 English
3        2          Linear Algebra
4        1           World History
5        4  Multivariable Calculus
6        1              Psychology
7        3              Government
8        4           Physics (E&M)

说明:

In [15]: b.groupby('User_Id', as_index=False)[['Coursework']].agg(', '.join)
Out[15]:
   User_Id                               Coursework
0        1  Pre Calculus, World History, Psychology
1        2                Chemistry, Linear Algebra
2        3                      English, Government
3        4    Multivariable Calculus, Physics (E&M)

答案 1 :(得分:1)

我认为您需要groupby apply joinmerge

df2 = df2.groupby('User Id')['Coursework'].apply(', '.join).reset_index()
#default inner join
df = pd.merge(df1, df2, on='User Id')
#for left join (if some values in df2 are missing)
#df = pd.merge(df1, df2, on='User Id', how='left')
print (df)
   User Id  Age                               Coursework
0        1   18  Pre Calculus, World History, Psychology
1        2   17                Chemistry, Linear Algebra
2        3   18                      English, Government
3        4   16    Multivariable Calculus, Physics (E&M)

concat的另一个解决方案:

df2 = df2.groupby('User Id')['Coursework'].apply(', '.join)
df1 = df1.set_index('User Id')
df = pd.concat([df1, df2], axis=1, join='inner').reset_index()
print (df)
   User Id  Age                               Coursework
0        1   18  Pre Calculus, World History, Psychology
1        2   17                Chemistry, Linear Algebra
2        3   18                      English, Government
3        4   16    Multivariable Calculus, Physics (E&M)