仅将一个键列复制到合并的DataFrame中

Ale*_*lex 11 python merge pandas

请考虑以下DataFrame:

df1 = pd.DataFrame({'a': [0, 1, 2, 3], 'b': list('abcd')})
df2 = pd.DataFrame({'c': list('abcd'), 'd': 'Alex'})
Run Code Online (Sandbox Code Playgroud)

在这个例子中,df1['b']并且df2['c']是关键列.合并时:

df1.merge(df2, left_on='b', right_on='c')
   a  b  c     d
0  0  a  a  Alex
1  1  b  b  Alex
2  2  c  c  Alex
3  3  d  d  Alex
Run Code Online (Sandbox Code Playgroud)

当我只需要一个时,我最终得到了结果DataFrame中的两个键列.我一直在用:

df1.merge(df2, left_on='b', right_on='c').drop('c', axis='columns')
Run Code Online (Sandbox Code Playgroud)

有没有办法只保留一个关键列?

sac*_*cuL 9

一种方法是设置bc为您的帧分别索引,使用join之后reset_index:

df1.set_index('b').join(df2.set_index('c')).reset_index()

   b  a     d
0  a  0  Alex
1  b  1  Alex
2  c  2  Alex
3  d  3  Alex
Run Code Online (Sandbox Code Playgroud)

这将比merge/drop大型数据帧上的方法更快,主要是因为drop速度慢.@Bill的方法比我的建议更快,而@WB和@PiRsquared轻松超过其他建议:

import timeit

df1 = pd.concat((df1 for _ in range(1000)))
df2 = pd.concat((df2 for _ in range(1000)))

def index_method(df1 = df1, df2 = df2):
    return df1.set_index('b').join(df2.set_index('c')).reset_index()


def merge_method(df1 = df1, df2=df2):
    return df1.merge(df2, left_on='b', right_on='c').drop('c', axis='columns')

def rename_method(df1 = df1, df2 = df2):
    return df1.rename({'b': 'c'}, axis=1).merge(df2)

def index_method2(df1 = df1, df2 = df2):
    return df1.join(df2.set_index('c'), on='b')

def assign_method(df1 = df1, df2 = df2):
    return df1.set_index('b').assign(c=df2.set_index('c').d).reset_index()

def map_method(df1 = df1, df2 = df2):
    return df1.assign(d=df1.b.map(dict(df2.values)))

>>> timeit.timeit(index_method, number=10) / 10
0.7853091600998596
>>> timeit.timeit(merge_method, number=10) / 10
1.1696729859002517
>>> timeit.timeit(rename_method, number=10) / 10
0.4291436871004407
>>> timeit.timeit(index_method2, number=10) / 10
0.5037374985004135
>>> timeit.timeit(assign_method, number=10) / 10
0.0038641377999738325
>>> timeit.timeit(map_method, number=10) / 10
0.006620216699957382
Run Code Online (Sandbox Code Playgroud)

  • `df1.join(df2.set_index('c'),on ='b')` (3认同)
  • 你想测试我的速度吗? (2认同)
  • @WB,我刚刚做了,它的***远远快了! (2认同)

Bil*_*ill 6

另一种方法是给b和c指定相同的名称.至少对于合并操作.

df1.rename({'b': 'c'}, axis=1).merge(df2)
   a  c     d
0  0  a  Alex
1  1  b  Alex
2  2  c  Alex
3  3  d  Alex
Run Code Online (Sandbox Code Playgroud)


Sco*_*ton 5

或者使用一个set_indexleft_index=Trueright_onparamater:

df1.set_index('b').merge(df2, left_index=True, right_on='c')
Run Code Online (Sandbox Code Playgroud)

输出:

   a  c     d
0  0  a  Alex
1  1  b  Alex
2  2  c  Alex
3  3  d  Alex
Run Code Online (Sandbox Code Playgroud)