Pandas 比较数据帧并添加列
我有两个数据帧,如下所示Pandas 比较数据帧并添加列,pandas,dataframe,compare,Pandas,Dataframe,Compare,我有两个数据帧,如下所示 df1 df2 A A C A1 A1 C1 A2 A2 C2 A3 A3 C3 A1 A4 C4 A2 A3 A4 列“A”的值在df2中的列“C”中定义。 我想向df1添加一个新列,其中列B的值来自df2列“C” 最终的df1应该是这样的 df1 A B A1 C1 A2 C2 A3 C3 A1 C1 A2 C2 A3
df1 df2
A A C
A1 A1 C1
A2 A2 C2
A3 A3 C3
A1 A4 C4
A2
A3
A4
列“A”的值在df2中的列“C”中定义。
我想向df1添加一个新列,其中列B的值来自df2列“C”
最终的df1应该是这样的
df1
A B
A1 C1
A2 C2
A3 C3
A1 C1
A2 C2
A3 C3
A4 C4
我可以在df2上循环,并将值添加到df1,但由于数据量巨大,这非常耗时
for index, row in df2.iterrows():
df1.loc[df1.A.isin([row['A']]), 'B']= row['C']
有人能帮助我理解如何在不循环df2的情况下解决这个问题吗
谢谢IIUC您可以合并并重命名该列
df1.merge(df2, on='A', how='left').rename(columns={'C':'B'})
In [103]:
df1 = pd.DataFrame({'A':['A1','A2','A3','A1','A2','A3','A4']})
df2 = pd.DataFrame({'A':['A1','A2','A3','A4'], 'C':['C1','C2','C4','C4']})
merged = df1.merge(df2, on='A', how='left').rename(columns={'C':'B'})
merged
Out[103]:
A B
0 A1 C1
1 A2 C2
2 A3 C4
3 A1 C1
4 A2 C2
5 A3 C4
6 A4 C4
您可以通过系列使用:
df1['B'] = df1.A.map(df2.set_index('A')['C'])
print (df1)
A B
0 A1 C1
1 A2 C2
2 A3 C3
3 A1 C1
4 A2 C2
5 A3 C3
6 A4 C4
它与dict的映射相同:
d = df2.set_index('A')['C'].to_dict()
print (d)
{'A4': 'C4', 'A3': 'C3', 'A2': 'C2', 'A1': 'C1'}
df1['B'] = df1.A.map(d)
print (df1)
A B
0 A1 C1
1 A2 C2
2 A3 C3
3 A1 C1
4 A2 C2
5 A3 C3
6 A4 C4
计时:
len(df1)=7
:
In [161]: %timeit merged = df1.merge(df2, on='A', how='left').rename(columns={'C':'B'})
1000 loops, best of 3: 1.73 ms per loop
In [162]: %timeit df1['B'] = df1.A.map(df2.set_index('A')['C'])
The slowest run took 4.44 times longer than the fastest. This could mean that an intermediate result is being cached.
1000 loops, best of 3: 873 µs per loop
len(df1)=70k
:
In [164]: %timeit merged = df1.merge(df2, on='A', how='left').rename(columns={'C':'B'})
100 loops, best of 3: 12.8 ms per loop
In [165]: %timeit df1['B'] = df1.A.map(df2.set_index('A')['C'])
100 loops, best of 3: 6.05 ms per loop
基于该方法,这里有三种不同索引方案的方法-
df1['B'] = df2.C[df2.A.searchsorted(df1.A)].values
df1['B'] = df2.C[df2.A.searchsorted(df1.A)].reset_index(drop=True)
df1['B'] = df2.C.values[df2.A.searchsorted(df1.A)]
谢谢大家的建议。我使用这个解决方案,因为它会将df2中的其他列合并到df1。谢谢@edchumtmerge
和map
之间还有语义上的区别,如果df1中的查找在df2中不存在,那么merge
将插入NaN
,而map
将抛出keyrerror