Удалите строки, существующие в другом фрейме данных, используя 2 разных столбца - PullRequest
2 голосов
/ 16 июня 2020

У меня возникла следующая проблема: Получено 2 pandas фреймов данных, например:

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. Поскольку у меня есть несколько дополнительных столбцов с разными данными в исходных DataFrames, я не могу просто указать 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 столбец для поиска существующих данных, но проблема в том, что мне нужно удалить строки, только если система и электронные письма одинаковы. например, если я получил тот же адрес электронной почты, но с другой системой в строке, он должен остаться.

Ответы [ 2 ]

2 голосов
/ 16 июня 2020

IIU C, вы можете выполнить левое слияние и указать значения, которые есть только в левом фрейме данных.

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
0 голосов
/ 16 июня 2020

Оставить в новой строке

#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)

# Use np.where to check and attribu 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...