请考虑以下数据框:
df1 = pd.DataFrame({'a': [0, 1, 2, 3], 'b': list('abcd')})
df2 = pd.DataFrame({'c': list('abcd'), 'd': 'Alex'})
在这种情况下,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
当我只需要一个时,我在结果DataFrame中得到两个关键列。我一直在使用:
df1.merge(df2, left_on='b', right_on='c').drop('c', axis='columns')
有没有办法只保留一个关键列?
答案 0 :(得分:7)
一种方法是分别将b
和c
设置为帧的索引,并使用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
这在大型数据帧上比merge/drop
方法要快,主要是因为drop
很慢。 @Bill的方法比我的建议快,而@ W-B和@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
答案 1 :(得分: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
答案 2 :(得分:5)
或使用一个set_index
和left_index=True
和right_on
参数:
df1.set_index('b').merge(df2, left_index=True, right_on='c')
输出:
a c d
0 0 a Alex
1 1 b Alex
2 2 c Alex
3 3 d Alex
答案 3 :(得分:4)
map
我被迫放下讨厌的(不推荐)方法,因为我不小心将重复的答案发布给其他人。
df1.assign(d=df1.b.map(dict(df2.values)))
a b d
0 0 a Alex
1 1 b Alex
2 2 c Alex
3 3 d Alex
答案 4 :(得分:4)
在set_index
之后,您可以直接assign
值
df1.set_index('b').assign(c=df2.set_index('c').d).reset_index()
Out[233]:
b a c
0 a 0 Alex
1 b 1 Alex
2 c 2 Alex
3 d 3 Alex