【发布时间】:2018-12-01 15:55:38
【问题描述】:
我正在尝试在 Python 中执行一个与 Excel 中的 VLOOKUP 非常相似的操作。 StackOverflow 上有很多与此相关的问题,但它们都与这个用例略有不同。希望任何人都可以指导我正确的方向。我有以下两个熊猫数据框:
df1 = pd.DataFrame({'Invoice': ['20561', '20562', '20563', '20564'],
'Currency': ['EUR', 'EUR', 'EUR', 'USD']})
df2 = pd.DataFrame({'Ref': ['20561', 'INV20562', 'INV20563BG', '20564'],
'Type': ['01', '03', '04', '02'],
'Amount': ['150', '175', '160', '180'],
'Comment': ['bla', 'bla', 'bla', 'bla']})
print(df1)
Invoice Currency
0 20561 EUR
1 20562 EUR
2 20563 EUR
3 20564 USD
print(df2)
Ref Type Amount Comment
0 20561 01 150 bla
1 INV20562 03 175 bla
2 INV20563BG 04 160 bla
3 20564 02 180 bla
现在我想创建一个新的数据框 (df3),在其中根据发票编号将两者结合起来。问题是发票号码并不总是“完全匹配”,但有时在 df2['Ref'] 中是“部分匹配”。因此,加入“发票”并没有提供所需的输出,因为它没有复制发票 20562 和 20563 的数据,见下文:
df3 = df1.join(df2.set_index('Ref'), on='Invoice')
print(df3)
Invoice Currency Type Amount Comment
0 20561 EUR 01 150 bla
1 20562 EUR NaN NaN NaN
2 20563 EUR NaN NaN NaN
3 20564 USD 02 180 bla
有没有办法加入部分比赛?我知道如何用正则表达式“清理”df2['Ref'],但这不是我想要的解决方案。使用 for 循环,我有很长的路要走,但这不是很 Pythonic。
df4 = df1.copy()
for i, row in df1.iterrows():
tmp = df2[df2['Ref'].str.contains(row['Invoice'])]
df4.loc[i, 'Amount'] = tmp['Amount'].values[0]
print(df4)
Invoice Currency Amount
0 20561 EUR 150
1 20562 EUR 175
2 20563 EUR 160
3 20564 USD 180
str.contains() 能否以更优雅的方式使用?非常感谢您的帮助!
【问题讨论】:
标签: python python-3.x pandas dataframe join