Python 复杂数据帧操作
我有一个数据框,看起来像这样:Python 复杂数据帧操作,python,pandas,dataframe,Python,Pandas,Dataframe,我有一个数据框,看起来像这样: 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,10
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
i、 e.只应标记第一行,因为(在ID2中)与帐户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”您可以使用:
其中:
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”您的解释有点不清楚,但我想您需要这样:
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中,所以只选择了第一行。您的解释有点不清楚,但我认为您希望:
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”与条件匹配,因为第二行的ID2中的“A”与条件匹配,所以只选择了第一行。我在94500中更新的示例E中发布的稍微修改的数据集不起作用,ID2与ID1中的E匹配,所以最后一行也应该为真,否?在我在94500中更新的示例E中发布的稍微修改的数据集下,它不起作用,ID2与ID1中的E匹配,所以最后一行也应该是正确的,否?我在尝试在稍微不同的场景中使用代码时遇到了问题。如果我有另一个名为“Prod”的列,而我现在想根据帐户94500和Prod 6901进行匹配,那么我无法让代码正常工作!将熊猫作为pd df=pd.DataFrame({'ID1':['A'、'B'、'C'、'D'、'E']、\'ID2':['B'、'A'、'D'、'C'、'E']、\'Account':['94000'、'94000'、'18300'、'94500']、\'Prod':['6901'、'0'、'0'、'0'、'0'、'0'、'0'、'Amount':[100,50]、'Match'、'94500'、'94000'、'94000'、'dfI在尝试在稍微不同的场景中使用您的代码时遇到了问题。如果我有另一个名为“Prod”的列,而我现在想根据帐户94500和Prod 6901进行匹配,那么我无法让代码正常工作!数据帧({'ID1':['A'、'B'、'C'、'D'、'E']、'ID2':['B'、'A'、'D'、'C'、'E']、'Account':['94000'、'94500'、'94000'、'18300'、'94500']、'Prod':['6901'、'0'、'0'、'0'、'0'、'0'、'0'、'0'、'Amount':[100、-100、-100、-100、-50、-50100]、'Match'、'18300'、'。如果我理解正确,则不应该存在与prod为6901和帐户为94500的匹配项。我在尝试在稍微不同的场景中使用您的代码时遇到了问题。如果我有另一个名为“Prod”的列,而我现在想根据帐户94500和Prod 6901进行匹配,那么我无法让代码正常工作!将熊猫作为pd df=pd.DataFrame({'ID1':['A'、'B'、'C'、'D'、'E']、\'ID2':['B'、'A'、'D'、'C'、'E']、\'Account':['94000'、'94000'、'18300'、'94500']、\'Prod':['6901'、'0'、'0'、'0'、'0'、'0'、'0'、'Amount':[100,50]、'Match'、'94500'、'94000'、'94000'、'dfI在尝试在稍微不同的场景中使用您的代码时遇到了问题。如果我有另一个名为“Prod”的列,而我现在想根据帐户94500和Prod 6901进行匹配,那么我无法让代码正常工作!数据帧({'ID1':['A'、'B'、'C'、'D'、'E']、'ID2':['B'、'A'、'D'、'C'、'E']、'Account':['94000'、'94500'、'94000'、'18300'、'94500']、'Prod':['6901'、'0'、'0'、'0'、'0'、'0'、'0'、'0'、'Amount':[100、-100、-100、-100、-50、-50100]、'Match'、'18300'、'。如果我理解正确的话,应该没有与6901的prod和94500的account相匹配的更改条件以解决您的情况。