Pandas加入具有不同名称的列

时间:2016-11-13 03:06:33

标签: python sql pandas merge

我有两个不同的数据框,我想要执行一些SQL操作。不幸的是,正如我使用的数据一样,拼写通常是不同的。

请参阅下面的示例,我认为语法看起来像userid属于df1,而username属于df2。有人帮帮我吗?

 # not working - I assume some syntax issue?
pd.merge(df1, df2, on = [['userid'=='username', 'column1']], how = 'left')

2 个答案:

答案 0 :(得分:8)

如果名称不同,请使用xxx_on参数代替on=

pd.merge(df1, df2, left_on=  ['userid', 'column1'],
                   right_on= ['username', 'column1'], 
                   how = 'left')

答案 1 :(得分:1)

另一种方法是使用join将右侧DataFrame的索引设置为列['username', 'column1']

df1.join(df2.set_index(['username', 'column1']), on=['userid', 'column1'], how='left')

join的输出的匹配键从两个不同命名的键列useridusername合并到一个以df1userid的键列;而merge的输出将两者保持为单独的列。为了说明,请考虑以下示例:

import numpy as np
import pandas as pd

df1 = pd.DataFrame({'ID': [1,2,3,4,5,6], 'pID' : [21,22,23,24,25,26], 'Values' : [435,33,45,np.nan,np.nan,12]})
##    ID  Values  pID
## 0   1   435.0   21
## 1   2    33.0   22
## 2   3    45.0   23
## 3   4     NaN   24
## 4   5     NaN   25
## 5   6    12.0   26

df2 = pd.DataFrame({'ID' : [4,4,5], 'pid' : [24,25,25], 'Values' : [544, 545, 676]})
##    ID  Values  pid
## 0   4     544   24
## 1   4     545   25
## 2   5     676   25

pd.merge(df1, df2, how='left', left_on=['ID', 'pID'], right_on=['ID', 'pid']))
##    ID  Values_x  pID  Values_y   pid
## 0   1     435.0   21       NaN   NaN
## 1   2      33.0   22       NaN   NaN
## 2   3      45.0   23       NaN   NaN
## 3   4       NaN   24     544.0  24.0
## 4   5       NaN   25     676.0  25.0
## 5   6      12.0   26       NaN   NaN

df1.join(df2.set_index(['ID','pid']), how='left', on=['ID','pID'], lsuffix='_x', rsuffix='_y'))
##    ID  Values_x  pID  Values_y
## 0   1     435.0   21       NaN
## 1   2      33.0   22       NaN
## 2   3      45.0   23       NaN
## 3   4       NaN   24     544.0
## 4   5       NaN   25     676.0
## 5   6      12.0   26       NaN

在这里,我们还需要在lsuffix中指定rsuffixjoin,以区分输出中的重叠列Value。可以看到,merge的输出包含来自右侧pid的额外的DataFrame列,鉴于合并的上下文,恕我直言是不必要的。还要注意,dtype列的pid已更改为float64,这是由于由于从不匹配的行中引入了NaN而导致的向上广播。

由于在右侧set_index上调用DataFrame会产生一些开销,因此以性能为代价获得了这种美学输出。但是,快速而肮脏的配置文件表明这并不太可怕,大致30%,这可能是值得的:

sz = 1000000 # one million rows
df1 = pd.DataFrame({'ID': np.arange(sz), 'pID' : np.arange(0,2*sz,2), 'Values' : np.random.random(sz)})
df2 = pd.DataFrame({'ID': np.concatenate([np.arange(sz/2),np.arange(sz/2)]), 'pid' : np.arange(0,2*sz,2), 'Values' : np.random.random(sz)})

%timeit pd.merge(df1, df2, how='left', left_on=['ID', 'pID'], right_on=['ID', 'pid'])
## 818 ms ± 33.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

%timeit df1.join(df2.set_index(['ID','pid']), how='left', on=['ID','pID'], lsuffix='_x', rsuffix='_y')
## 1.04 s ± 18.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)