在pandas中,将两个数据框根据共同列进行合并。

51
我有一个数据框 df:
id   name   count
1    a       10
2    b       20
3    c       30
4    d       40
5    e       50

这里我有另一个数据框df2:
id1  price   rating
 1     100     1.0
 2     200     2.0
 3     300     3.0
 5     500     5.0

我想要根据id和id1这两列将这两个数据框连接起来。这是df3的一个例子:
id   name   count   price   rating
1    a       10      100      1.0
2    b       20      200      2.0
3    c       30      300      3.0
4    d       40      Nan      Nan
5    e       50      500      5.0

我应该使用 `df.merge` 还是 `pd.concat`?

@piRSquared 先生,两个答案都是完全正确的 :) 只有一个问题,假设我正在处理两个大约有4百万行的数据框。 我想知道,在连接、合并和映射之间,哪个是最优化的方式? - Shubham R
1
两者在本质上是相同的。我不在乎你选择哪一个。@jezrael和我总是在SO上。我们会用一种或另一种方式获得我们的声望。我更关心确保这15个声望不会浪费。因为他在这方面比我快了几微秒,所以选择他的吧;-) - piRSquared
2个回答

82

使用merge函数:

print (pd.merge(df1, df2, left_on='id', right_on='id1', how='left').drop('id1', axis=1))
   id name  count  price  rating
0   1    a     10  100.0     1.0
1   2    b     20  200.0     2.0
2   3    c     30  300.0     3.0
3   4    d     40    NaN     NaN
4   5    e     50  500.0     5.0

另一个解决方案是简单地重命名列:

print (pd.merge(df1, df2.rename(columns={'id1':'id'}), on='id',  how='left'))
   id name  count  price  rating
0   1    a     10  100.0     1.0
1   2    b     20  200.0     2.0
2   3    c     30  300.0     3.0
3   4    d     40    NaN     NaN
4   5    e     50  500.0     5.0

如果只需要 price 这一列,最简单的方法是使用map函数:

df1['price'] = df1.id.map(df2.set_index('id1')['price'])
print (df1)
   id name  count  price
0   1    a     10  100.0
1   2    b     20  200.0
2   3    c     30  300.0
3   4    d     40    NaN
4   5    e     50  500.0

另外还有两种解决方案:

print (pd.merge(df1, df2, left_on='id', right_on='id1', how='left')
         .drop(['id1', 'rating'], axis=1))
   id name  count  price
0   1    a     10  100.0
1   2    b     20  200.0
2   3    c     30  300.0
3   4    d     40    NaN
4   5    e     50  500.0

print (pd.merge(df1, df2[['id1','price']], left_on='id', right_on='id1', how='left')
         .drop('id1', axis=1))
   id name  count  price
0   1    a     10  100.0
1   2    b     20  200.0
2   3    c     30  300.0
3   4    d     40    NaN
4   5    e     50  500.0

你提出的两种方式都是正确的,对吗? - Shubham R
是的,所有解决方案都是正确的。如果需要添加更多列,更好的选择是使用“join”(默认情况下不必删除列,左连接),但如果只需要添加一列,“map”更快。 - jezrael
对于两个非常大的数据框(每个数据框大约有400万行),我应该使用合并(merge)还是映射(map)?哪一个需要更少的时间来完成? - Shubham R
你需要添加一列还是两列? - jezrael
只是一个问题,我的需求可能会改变,有时候是一列,有时候是两列。在这两种情况下哪个更好? - Shubham R
显示剩余6条评论

11

join使用索引进行合并,除非我们指定要使用的列。但是,我们只能为'left'数据框指定一列而不是索引。

策略:

  • df2使用set_index将其设置为id1
  • 使用join函数,以df作为左数据框,以id作为on参数。注意,我可以在df上使用set_index('id')来避免使用on参数。但这样做会导致重置索引后无法保留该列,所以我选择了前者。

df.join(df2.set_index('id1'), on='id')

   id name  count  price  rating
0   1    a     10  100.0     1.0
1   2    b     20  200.0     2.0
2   3    c     30  300.0     3.0
3   4    d     40    NaN     NaN
4   5    e     50  500.0     5.0
如果你只想要从df2中获取price
df.join(df2.set_index('id1')[['price']], on='id')


   id name  count  price
0   1    a     10  100.0
1   2    b     20  200.0
2   3    c     30  300.0
3   4    d     40    NaN
4   5    e     50  500.0

如果我只想从df2中选择一个名为“price”的列,应该怎么做? - Shubham R

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