首页 > 解决方案 > 如何从一个数据框中删除属于另一个数据框的所有行?

问题描述

我有两个这样的数据框

import pandas as pd

df1 = pd.DataFrame(
    {
        'A': list('abcaewar'),
        'B': list('ghjglmgb'),
        'C': list('lkjlytle'),
        'ignore': ['stuff'] * 8
    }
)

df2 = pd.DataFrame(
    {
        'A': list('abfu'),
        'B': list('ghio'),
        'C': list('lkqw'),
        'stuff': ['ignore'] * 4
    }
)

我想删除df1where中的所有行AB并且C与中的值相同df2,因此在上述情况下,预期结果是

   A  B  C ignore
0  c  j  j  stuff
1  e  l  y  stuff
2  w  m  t  stuff
3  r  b  e  stuff

实现这一目标的一种方法是

comp_columns = ['A', 'B', 'C']
df1 = df1.set_index(comp_columns)
df2 = df2.set_index(comp_columns)

keep_ind = [
    ind for ind in df1.index if ind not in df2.index
]

new_df1 = df1.loc[keep_ind].reset_index()

有没有人看到这样做的更直接的方法,它避免了reset_index()操作和循环来识别非重叠索引,例如通过屏蔽的市场方式?理想情况下,我不必对列进行硬编码,但可以在上面的列表中定义它们,因为我有时需要 2、有时 3 或有时需要 4 或更多列来删除。

标签: pythonpandas

解决方案


DataFrame.merge与可选参数一起使用indicator=True,然后使用布尔掩码过滤以下行df1

df3 = df1.merge(df2[['A', 'B', 'C']], on=['A', 'B', 'C'], indicator=True, how='left')
df3 = df3[df3.pop('_merge').eq('left_only')]

结果:

# print(df3)

   A  B  C ignore
2  c  j  j  stuff
4  e  l  y  stuff
5  w  m  t  stuff
7  r  b  e  stuff

推荐阅读