为了账号安全,请及时绑定邮箱和手机立即绑定

如果某些行值与第二个 DataFrame 中的行值相同,则有效地从 DataFrame 中删除行

如果某些行值与第二个 DataFrame 中的行值相同,则有效地从 DataFrame 中删除行

幕布斯6054654 2021-08-24 16:42:37
import pandas as pddf1 = pd.DataFrame({'id':   [ 1,  1,  1,  2,  2,  2,  3,  3,  3],                     'nr':   [91, 92, 93, 91, 92, 93, 91, 92, 93],                     'val_a':[22, 23, 24, 33, 34, 35, 44, 43, 42]})df2 = pd.DataFrame({'id':   [ 1,  1,  2,  3,  4,  4,  3,  5],                     'nr':   [91, 92, 91, 99, 92, 93, 92, 99],                     'val_a':[72, 27, 74, 83, 84, 85, 84, 83]})def eliminate1 ():     for i1, row1 in df1.iterrows():        for i2, row2 in df2.iterrows():            if row1['id'] == row2['id'] and row1['nr'] == row2['nr']:                df1.drop(i1, inplace=True)    df1.reset_index(drop=True, inplace=True)    print(df1)eliminate1()我想删除 df1 中的所有行,其中 'id' AND 'nr' 在 df2 的任何行中具有相等的值。消除1()效果很好,见下面的结果,但在大数据集的情况下非常慢。这是 df1 和 df2:   id  nr  val_a0   1  91     221   1  92     232   1  93     243   2  91     334   2  92     345   2  93     356   3  91     447   3  92     438   3  93     42    id  nr  val_a0   1  91     721   1  92     272   2  91     743   3  99     834   4  92     845   4  93     856   3  92     847   5  99     83 这里的结果应该是这样的:   id  nr  val_a0   1  93     241   2  92     342   2  93     353   3  91     444   3  93     42有谁知道如何编写更快的代码和/或使用已经存在的函数?
查看完整描述

3 回答

?
郎朗坤

TA贡献1921条经验 获得超9个赞

merge

您可以merge使用indicator=True并仅包含标记为 的那些行'left_only'。


res = df1.merge(df2.drop('val_a', 1), how='left', on=['id', 'nr'], indicator=True)

res = res.loc[res['_merge'] == 'left_only'].drop('_merge', 1)


print(res)


   id  nr  val_a

2   1  93     24

4   2  92     34

5   2  93     35

6   3  91     44

8   3  93     42

该解决方案很容易适应任何条件,具体取决于'left_only'、'right_only'或'both'。


查看完整回答
反对 回复 2021-08-24
?
猛跑小猪

TA贡献1858条经验 获得超8个赞

isin将merge列压缩后的方法1tuple


df1[~df1[['id','nr']].apply(tuple,1).isin(df2[['id','nr']].apply(tuple,1))]

Out[43]: 

   id  nr  val_a

2   1  93     24

4   2  92     34

5   2  93     35

6   3  91     44

8   3  93     42

方法二numpy广播


s1=df1[['id','nr']].values

s2=df2[['id','nr']].values

df1[~np.any(np.all(s1==s2[:,None],-1),0)]

Out[64]: 

   id  nr  val_a

2   1  93     24

4   2  92     34

5   2  93     35

6   3  91     44

8   3  93     42

我的方法计时


%timeit df1[~df1[['id','nr']].apply(tuple,1).isin(df2[['id','nr']].apply(tuple,1))]

100 loops, best of 3: 3.67 ms per loop

def m2():

    s1 = df1[['id', 'nr']].values

    s2 = df2[['id', 'nr']].values

    return df1[~np.any(np.all(s1 == s2[:, None], -1), 0)]

%timeit m2()

1000 loops, best of 3: 926 µs per loop


查看完整回答
反对 回复 2021-08-24
?
aluckdog

TA贡献1847条经验 获得超7个赞

能inner join解决你的问题吗?获取与条件匹配的参数的索引,然后将其过滤掉。reset_index()如果你想这样做,你只需要事后去做。


df3 = df1.merge(df2, how = 'inner', on = ['id','nr']).reset_index()

id_list = df3['id'].tolist()

df4 = df1[~df1['id'].isin(id_list)]


查看完整回答
反对 回复 2021-08-24
  • 3 回答
  • 0 关注
  • 263 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号