我的数据框看起来像这样:
import pandas as pd
df= pd.DataFrame({'ID1':['A','B','C','D','E'],\
'ID2':['B','A','D','C','E'],\
'Account':['94000','94500','94000','18300','94500'],\
'Amount':[100,-100,50,-50,100],\
'Match':['-','-','-','-','-']})
df
我正在努力寻找一种最有效的方法,以确定“ID1”中的某个项目在“ID2”中的特定值为何值。例如,条件为Account = 94500应该产生:
df= pd.DataFrame({'ID1':['A','B','C','D','E'],\
'ID2':['B','A','D','C','E'],\
'Account':['94000','94500','94000','18300','94500'],\ 'Amount':[100,-100,50,-50,200],'Match':['True','-','-','-','-']})
df
即。只应标记第一行,因为A(在ID2中)与Account 94500匹配
答案 0 :(得分:2)
您可以使用pandas apply:
df['Match'] = df['ID1'].apply(lambda x: any((df['ID2']==x) & (df['Account']=='94500')))
给出了:
Account Amount ID1 ID2 Match
0 94000 100 A B True
1 94500 -100 B A False
2 94000 50 C D False
3 18300 -50 D C False
4 94500 100 E E True
用语言来说,逻辑是:
“对于ID1中的每个元素(apply
),检查是否至少有(any
)数据帧的一行ID2 = ID1和Account = 94500”
答案 1 :(得分:2)
你的解释有点不清楚,但我想你想要这个:
mask = df[df.Account == '94500'].ID2
df.loc[df.ID1.isin(mask),"Match"] = True
Account Amount ID1 ID2 Match
0 94000 100 A B True
1 94500 -100 B A -
2 94000 50 C D -
3 18300 -50 D C -
4 94500 100 E E True
同时比较两个正确的答案只是为了好玩。
%timeit -r 10 df['Match'] = df['ID1'].apply(lambda x: any((df['ID2']==x) & (df['Account']=='94500')))
100 loops, best of 10: 4.21 ms per loop
%timeit -r 10 df.loc[df.ID1.isin(df[df.Account == '94500'].ID2),"Match"] = True
1000 loops, best of 10: 1.48 ms per loop
更新以解决新用例
您提到您有两个要使用的列存在问题。我不确定我是否理解正确,但这是我的看法。假设您有另一个变量Prod
,并且您希望在Account == 94500
和Prod == 6901
上同时选择它们。
在这种情况下:
df= pd.DataFrame({'ID1':['A','B','C','D','E'],\
'ID2':['B','A','D','C','E'],\
'Account':['94000','94500','94000','18300','94500'],\
'Amount':[100,-100,50,-50,100],\
'Match':['-','-','-','-','-'],\
'Prod':[0,6901,0,0,0]
})
mask = df[(df.Account == '94500') & (df.Prod == 6901)].ID2
df.loc[df.ID1.isin(mask),"Match"] = True
结果:
Account Amount ID1 ID2 Match Prod
0 94000 100 A B True 0
1 94500 -100 B A - 6901
2 94000 50 C D - 0
3 18300 -50 D C - 0
4 94500 100 E E - 0
现在只有ID1中的'A'符合条件,因为'A'在第二行的ID2中,所以只选择了第一行。