使用Pandas从另一个数据框中删除一个数据框

vu8f3i0k  于 2023-04-28  发布在  其他
关注(0)|答案(7)|浏览(180)

我有两个不同大小的 Dataframe (df1df2)。我想从df1中删除所有存储在df2中的行。
如果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)
ubby3x7f

ubby3x7f1#

使用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
krcsximq

krcsximq2#

我发现的最干净的方法是使用drop from pandas,使用你想要删除的dataframe的索引:

df1.drop(df2.index, axis=0,inplace=True)
jckbn6z7

jckbn6z73#

可以使用np.in1d检查df1中的任何行是否存在于df2中。然后将其用作反向掩码来从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
ubby3x7f

ubby3x7f4#

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
hiz5n14c

hiz5n14c5#

我认为最干净的方法可以是:
我们有基本 Dataframe D并且想要移除子集D1。令输出为D2

D2 = pd.DataFrame(D, index = set(D.index).difference(set(D1.index))).reset_index()
bmvo0sr5

bmvo0sr56#

我发现这个替代方案也很有用:

pd.concat([df1,df2], axis=0, ignore_index=True).drop_duplicates(subset=["A","B"],keep=False, ignore_index=True)

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

keep=False删除两个副本。
它不需要把所有相等的列放在两个df之间,所以我发现这有点容易。

tyu7yeag

tyu7yeag7#

使用此版本删除所有具有df1和df2之间的匹配索引的行,但我收到错误,因为它无法找到特定的索引,我关闭了错误,它工作得很好。谢谢:

df1.drop(df2.index, axis=0, inplace=True, errors = 'ignore')

相关问题