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相匹配的更改条件以解决您的情况。