2017-07-26 127 views
0

我有一个看起来是这样的一个数据帧:复杂的熊猫数据帧操纵

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”用账户的特殊价值。例如,具有帐户的条件= 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)匹配帐号94500只

+0

它不适用于我已发布的稍有修改的数据集 –

+0

在更新的示例中,94500中的E和ID2中的E与ID1中的E匹配,因此最后一行也应该为True,否? – omdv

回答

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 == 94500Prod == 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在第二行,所以只有第一行被选中。

+0

我试图在稍微不同的场景中使用代码时偶然发现。如果我有另一个名为“Prod”的专栏,我现在想根据帐户94500和Prod 6901进行匹配,我无法使代码正常工作! import pandas as pd df = pd.DataFrame({'ID1':['A','B','C','D','E'],\ 'ID2':['B' ,'A','D','C','E'],\ '帐户':['94000','94500','94000','18300','94500'],\ 'Prod ':['6901','0','0','0','0'],\ '金额':[100,-100,50,-50,100],\ '匹配':[​​'' - ',' - ',' - ',' - ',' - ']}) df –

+0

我试图在稍微不同的场景中使用代码时偶然发现。如果我有另一个名为“Prod”的专栏,我现在想根据帐户94500和Prod 6901进行匹配,我无法使代码正常工作! df = pd。数据帧({ 'ID1':[ 'A', 'B', 'C', 'd', 'E'], 'ID2':[ 'B', 'A', 'd', 'C', 'E'], '帐户':[ '94000', '94500', '94000', '18300', '94500'], 'PROD':[ '6901', '0', '0','0 ”, '0'], '金额':[100,-100,50,-50,100], '匹配':[​​ ' - ', ' - ', ' - ', ' - ', ' - ']}) 。应该没有匹配6901的产品和94500的帐户 –

+0

如果我理解正确,则更改条件以解决您的问题。 – omdv

2

可以使用大熊猫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和帐户= 94500”