如果在另一数据框中找到其列值,则从数据框中删除该行

时间:2019-01-11 15:21:54

标签: python pandas dataframe

df1 = {
    'vouchers': [100, 200, 300, 400],
    'units': [11, 12, 12, 13],
    'some_other_data': ['a', 'b', 'c', 'd'],
    }
df2 = {
    'vouchers': [500, 200, 600, 300],
    'units': [11, 12, 12, 13],
    'some_other_data': ['b', 'd', 'c', 'a'],
    }

鉴于上面的两个数据框,我要执行以下操作:如果可以在df1中找到来自df2的凭证,并且其对应的单位相同,则从中删除整个凭证行df1

因此,在这种情况下,所需的输出将是:

df1 = {
    'vouchers': [100, 300, 400],
    'units': [11, 12, 13],
    'some_other_data': ['a', 'c', 'd'],
    }

实现此目标的最佳方法是什么?

6 个答案:

答案 0 :(得分:4)

您可以使用pd.Index.isin通过索引操作有效地做到这一点:

u = df1.set_index(['vouchers', 'units'])
df1[~u.index.isin(pd.MultiIndex.from_arrays([df2.vouchers, df2.units]))]

   vouchers  units some_other_data
0       100     11               a
2       300     12               c
3       400     13               d

答案 1 :(得分:3)

使用merge

处理indicator index之后,我们得到drop的需要删除之后
idx=df1.merge(df2,on=['vouchers','units'],indicator=True,how='left').\
     loc[lambda x : x['_merge']=='both'].index
df1=df1.drop(idx,axis=0)
df1
Out[374]: 
   vouchers  units some_other_data
0       100     11               a
2       300     12               c
3       400     13               d

答案 2 :(得分:2)

尽管我们有很多很好的答案,但是这些问题似乎很有趣,因此在进行学习时,我非常感兴趣,并希望通过使用布尔表达式来放置另一个看起来更简单的版本:

第一个数据框:

>>> df1
   vouchers  units some_other_data
0       100     11               a
1       200     12               b
2       300     12               c
3       400     13               d

第二个数据框:

>>> df2
   vouchers  units some_other_data
0       500     11               a
1       200     12               b
2       600     12               c
3       300     13               d

可能更简单的答案:

>>> df1[(df1 != df2).any(1)]
   vouchers  units some_other_data
0       100     11               a
2       300     12               c
3       400     13               d

解决方案2:使用merge + indicator + query

>>> df1.merge(df2, how='outer', indicator=True).query('_merge == "left_only"').drop('_merge', 1)
   vouchers  units some_other_data
0       100     11               a
2       300     12               c
3       400     13               d

解决方案3:

>>> df1[~df1.isin(df2).all(axis=1)]
   vouchers  units some_other_data
0       100     11               a
2       300     12               c
3       400     13               d

答案 3 :(得分:1)

通过pd.DataFrame.duplicated的一种可能性:

df = pd.concat([df1, df2], ignore_index=True)
df = df.loc[~df.duplicated(subset=['vouchers', 'units'], keep=False)]
df = df.reindex(df.index & df1.index)

print(df)

#   some_other_data  units  vouchers
# 0               a     11       100
# 2               c     12       300
# 3               d     13       400

答案 4 :(得分:0)

我的解决方案:

df1 = {
    'vouchers': [100, 200, 300, 400],
    'units': [11, 12, 12, 13],
    'some_other_data': ['a', 'b', 'c', 'd']
    }
df2 = {
    'vouchers': [500, 200, 600, 300],
    'units': [11, 12, 12, 13],
    'some_other_data': ['a', 'b', 'c', 'd']
    }  

y = 0
for x in range(len(df1['vouchers'])):
    if df1['vouchers'][x-y] == df2['vouchers'][x]:
        if df1['units'][x-y] == df2['units'][x]:
            for key in df1.keys():
                del df1[key][x]
            y += 1

答案 5 :(得分:0)

尝试一下,很简单:

excs = [] #will store the index of the values which are equal

for i, (key, value) in enumerate(zip(df1["vouchers"], df1["units"])):
  for key2, value2 in zip(df2["vouchers"], df2["units"]):
    if key == key2 and value == value2:
      excs.append(i)

for exc in excs:
  del(df1["vouchers"][exc])
  del(df1["units"][exc])