2017-06-14 183 views
1

我有两个不同大小的数据帧(df1df2)。我想从df1中删除存储在df2内的所有行。用Pandas从另一个数据帧中删除一个数据帧

所以,如果我有df2等于:

 A B 
0 wer 6 
1 tyu 7 

而且df1等于:

 A B C 
0 qwe 5 a 
1 wer 6 s 
2 wer 6 d 
3 rty 9 f 
4 tyu 7 g 
5 tyu 7 h 
6 tyu 7 j 
7 iop 1 k 

最终的结果应该是像这样:

 A B C 
0 qwe 5 a 
1 rty 9 f 
2 iop 1 k 

我能通过使用for循环实现我的目标,但我想知道是否有更好,更elega nt和有效的方式来执行此类操作。

这里是我的情况下写的代码,你需要它: 进口大熊猫作为PD

df1 = pd.DataFrame({'A' : ['qwe', 'wer', 'wer', 'rty', 'tyu', 'tyu', 'tyu', 'iop'], 
        'B' : [ 5,  6,  6,  9,  7,  7,  7,  1], 
        'C' : ['a' , 's', 'd', 'f', 'g', 'h', 'j', 'k']}) 

df2 = pd.DataFrame({'A' : ['wer', 'tyu'], 
        'B' : [ 6,  7]}) 

for i, row in df2.iterrows(): 
    df1 = df1[(df1['A']!=row['A']) & (df1['B']!=row['B'])].reset_index(drop=True) 

回答

4

使用merge与外与query过滤,最后删除辅助柱参加由drop

df = pd.merge(df1, df2, on=['A','B'], how='outer', indicator=True) 
     .query("_merge != 'both'") 
     .drop('_merge', axis=1) 
     .reset_index(drop=True) 
print (df) 
    A B C 
0 qwe 5 a 
1 rty 9 f 
2 iop 1 k 
+0

是否可以指定列名称'A'和'B'? –

+0

是的,当然,在' – jezrael

+0

dekujiu moc kamarad!上添加参数! –

2

您可以使用np.in1d检查df2中是否存在df1中的任何行。然后将其用作反转蒙版以从df1中选择行。

df1[~df1[['A','B']].apply(lambda x: np.in1d(x,df2).all(),axis=1)]\ 
        .reset_index(drop=True) 
Out[115]: 
    A B C 
0 qwe 5 a 
1 rty 9 f 
2 iop 1 k 
1

pandas有一个名为isin方法,但是这依赖于唯一索引。我们可以定义一个lambda函数来创建我们可以在df1df2的现有'A''B'中使用的列。然后,我们否定这一点(因为我们要的不是df2值),并重置索引:

import pandas as pd 

df1 = pd.DataFrame({'A' : ['qwe', 'wer', 'wer', 'rty', 'tyu', 'tyu', 'tyu', 'iop'], 
        'B' : [ 5,  6,  6,  9,  7,  7,  7,  1], 
        'C' : ['a' , 's', 'd', 'f', 'g', 'h', 'j', 'k']}) 

df2 = pd.DataFrame({'A' : ['wer', 'tyu'], 
        'B' : [ 6,  7]}) 

unique_ind = lambda df: df['A'].astype(str) + '_' + df['B'].astype(str) 
print df1[~unique_ind(df1).isin(unique_ind(df2))].reset_index(drop=True) 

印刷:

 A B C 
0 qwe 5 a 
1 rty 9 f 
2 iop 1 k 
0

我发现的最彻底的方法是使用的指数使用从大熊猫下降你想丢弃的数据帧:

df1.drop(df2.index, axis=0,inplace=True) 
相关问题