在python中的公共列上加入两个数据框

Posted

技术标签:

【中文标题】在python中的公共列上加入两个数据框【英文标题】:JOIN two dataframes on common column in python 【发布时间】:2017-05-18 16:51:55 【问题描述】:

我有一个数据框 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 先生,这两个答案都是绝对正确的 :) 不能同时选择两个,只有一个问题,假设我正在处理两个数据帧,每个数据帧大约 400 万行。我想要最快的方式,在join,merge and map 之间应该是最优化的方式 两者在本质上是相同的。我不在乎你选哪个。 @jezrael 和我总是这样。我们将以一种或另一种方式获得我们的代表。我更感兴趣的是确保这 15 个代表不会浪费。选择他的,因为他比我快几微秒;-) 【参考方案1】:

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

策略:

set_indexdf2id1 使用joindf 作为左侧数据框,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

如果你只想要来自df2price

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 我只需要选择 1 列“价格”,那么?【参考方案2】:

使用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

另外2个解决方案:

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

【讨论】:

保留这个答案,如果从 df2 我只需要选择 1 列“价格”,那么? 我不明白,你能解释一下吗? 决赛桌有id name count id1 price rating,但我只想要来自df2的price而不是rating,然后呢? 你建议的两种方法都是正确的,对吧? 是的,所有解决方案都是正确的。如果需要添加更多列,更好更好的是join(不需要删除列,默认左连接),但如果只添加一列map更快。

以上是关于在python中的公共列上加入两个数据框的主要内容,如果未能解决你的问题,请参考以下文章

在没有公共列的情况下连接两个数据框

将两个不相等的数据框与两个索引(日期时间和日期)上的部分公共元素合并

熊猫合并:合并同一列上的两个数据框,但保留不同的列

如何在没有公共密钥的情况下合并 Apache Spark 中的两个数据帧?

内连接恰好在一列上,而在另一列上模糊

根据线序加入两个熊猫数据框