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



我有两个不同大小的数据帧(df1 nad df2(。我想从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 循环来实现我的目标,但我想知道是否有更好、更优雅、更高效的方式来执行此类操作。

这是我编写的代码,以备不时之需:进口大熊猫作为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)

使用带有外部连接的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

我发现最干净的方法是使用要删除的数据帧的索引从熊猫中删除:

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

您可以使用 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

pandas有一个名为isin的方法,但这依赖于唯一的索引。我们可以定义一个 lambda 函数来创建我们可以在其中使用的列 从现有的'A''B' df1df2 .然后我们否定这一点(因为我们希望值不在 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
我认为

最干净的方法是:

我们有基本数据帧 D,想要删除子集 D1。让输出为 D2

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

我发现其他替代方案也很有用:

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 之间放置所有相等的列,所以我发现这更容易一些。

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

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

相关内容

  • 没有找到相关文章

最新更新