我有两个不同大小的数据框(df1
nad df2
)。我想从df1
中删除存储在df2
内的所有行。{/ p>
所以,如果我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循环实现我的目标,但我想知道是否有更好,更优雅和有效的方法来执行此类操作。
以下是我在需要时编写的代码: 将pandas导入为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)
答案 0 :(得分:7)
将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
答案 1 :(得分:3)
您可以使用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
答案 2 :(得分:2)
pandas
有一个名为isin
的方法,但这取决于唯一索引。我们可以定义一个lambda函数来创建我们可以在'A'
和'B'
df1
和df2
的现有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
中)并重置索引:
<Root>
<Parties>
<Party PartyId="Party_1">
<PartyTypeCode PartyTypeCode="Bastard"></PartyTypeCode>
<PersonInfo>
<FirstName>Jon</FirstName>
<LastName>Snow</LastName>
<Gender>M</Gender>
</PersonInfo>
<EmailAddress>knowsnothing@gmail.com</EmailAddress>
</Party>
<Party PartyId="Party_2">
<PartyTypeCode PartyTypeCode="Stark"></PartyTypeCode>
<PersonInfo>
<FirstName>Eddard</FirstName>
<LastName>Stark</LastName>
</PersonInfo>
</Party>
</Parties>
<MoreInfo>
<Parties>
<PartyRef PartyId="Party_1">
<PartyRole PartyRoleCode="Nights Watch"></PartyRole>
</PartyRef>
<PartyRef PartyId="Party_1">
<PartyRole PartyRoleCode="Wildling"></PartyRole>
</PartyRef>
<PartyRef PartyId="Party_2">
<PartyRole PartyRoleCode="Kings Hand"></PartyRole>
</PartyRef>
</Parties>
</MoreInfo>
</Root>
打印:
PartyRolecode FirstName LastName Gender Email Address
------------- --------- -------- ------ -------------
Nights Watch Jon Snow M knowsnothing@gmail.com
Wildling Jon Snow M knowsnothing@gmail.com
Kings Hand Eddard Stark
答案 3 :(得分:2)
我发现最干净的方法是使用你想要删除的数据帧的索引来使用pandas中的drop:
df1.drop(df2.index, axis=0,inplace=True)
答案 4 :(得分:0)
我认为最干净的方法可以是:
我们有基本数据帧D,并希望删除子集D1。令输出为D2
D2 = pd.DataFrame(D, index = set(D.index).difference(set(D1.index))).reset_index()