使用2个不同的列删除其他dataframe中存在的行

2024-09-28 20:46:01 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了以下问题:有2个数据帧,比如:

importdf:
     System   Email
 1   Basic    testimail@yahoo.com
 2   Basic    anotheremail@yahoo.com
 3   Backend  newemail@yahoo.com

userdf:
     System   Email
 1   Basic    testimail@yahoo.com
 2   Backend   anotheremail@yahoo.com
 3   Basic    newemail@yahoo.com

我需要做的是删除importdf中存在于userdf中的每一行。因为我在原始数据帧中获得了一些具有不同数据的额外列,所以我不能只告诉pandas删除重复的行。此时,我将使用以下代码来处理此问题:

importdf_system = importdf['System'].tolist()
importdf_emails = importdf['Email'].tolist()

userdf_system = userdf['System'].tolist()
userdf_emails = userdf['Email'].tolist()

importdf.reset_index(drop=True)
userdf.reset_index(drop=True)

counter = len(importdf)
for i in range(len(importdf)):
    counter = counter - 1
    print(counter)
    for j in range(len(userdf)):
        if "@" in str(importdf_emails[i]) and "@" in str(userdf_emails[j]) and str(importdf_emails[i]).lower() == str(userdf_emails[j]).lower():
            importdf = importdf.drop([i])

有时,该代码运行良好,但需要数小时才能运行,因为数据帧非常庞大。而且,有时,我会遇到类似KeyError: '[1782] not found in axis'的错误

我一直在寻找更好的方法,但没有找到有用的解决办法。找到了一种使用1列查找现有数据的方法,但问题是,只有在系统和电子邮件相同的情况下,我才需要删除行。例如,如果我收到同一封电子邮件,但同一行有不同的系统,它必须保持不变


Tags: 数据incomlenbasicemailcountersystem
2条回答

与新行保持一致

#Check column which is a concat of System and Email


 userdf['check']=userdf.System.str.cat(userdf.Email)
 importdf['check']=importdf.System.str.cat(importdf.Email)

#{}te

 res=userdf.assign(filter=np.where([x not in y for x, y in zip(userdf.check,importdf.check)],'drop','keep')).drop(columns=['check'])
print(res)

      System                Email    filter
1    Basic     testimail@yahoo.com   keep
2  Backend  anotheremail@yahoo.com   drop
3    Basic      newemail@yahoo.com   drop

IIUC,您可以执行左合并并指定仅在左数据帧中的值

new_df = (
    pd.merge(df1, df2, on=["System", "Email"], how="left", indicator=True)
    .query('_merge == "left_only"')
    .drop("_merge", 1)
)


print(new_df)

    System                   Email
1    Basic  anotheremail@yahoo.com
2  Backend      newemail@yahoo.com

细节

pd.merge(df1,df2,on=['System','Email'],how='left',indicator=True)

    System                   Email     _merge
0    Basic     testimail@yahoo.com       both # < we will drop this.
1    Basic  anotheremail@yahoo.com  left_only
2  Backend      newemail@yahoo.com  left_only

相关问题 更多 >