Как эффективно объединить и получить количество несовпадающих записей?

#python #pandas #dataframe #pandas-groupby #series

#python #pandas #фрейм данных #pandas-groupby #Серии

Вопрос:

У меня есть два фрейма данных, как показано ниже

 import pandas as pd
import numpy as np
source_df = pd.DataFrame({'source_value':['21ABCDE1','22CDEF2','23DEF3','24FGH4']})
client_df = pd.DataFrame({'source_value':['21ABCDE1','29SB','21ABCDE1','29SB','25FG','25FG','31DE','35DE']})
 

Что я хотел бы сделать, так это найти количество source_values , которое присутствует в client_df , но отсутствует в source_df .

Пожалуйста, обратите внимание, что могут быть дубликаты в client_df , но не в source_df

По сути, я должен идентифицировать их, поскольку они недействительны (потому что они отсутствуют в родительском фрейме данных, который есть source_df )

Я попробовал ниже, но это для совпадающих записей.

 pd.merge(
    source_df,client_df,
    how="inner",
    on = 'source_value').groupby('source_value').size()
 

Как я могу элегантно сделать это для non-matching записей, потому что у меня есть несколько миллионов данных (не менее 10 миллионов записей и может доходить до 15 миллионов).

Я ожидаю, что мой результат будет таким, как показано ниже

введите описание изображения здесь

Ответ №1:

Один из вариантов — получить source_value from source_df в виде набора, а затем отфильтровать и подсчитать значения в client_df :

 source_values = set(source_df.source_value.to_list())
client_df.source_value[lambda x: ~x.isin(source_values)].value_counts()

#29SB    2
#25FG    2
#35DE    1
#31DE    1
#Name: source_value, dtype: int64
 

Ответ №2:

 In []: client_df[~client_df.source_value.isin(source_df.source_value)].value_counts()
Out[]:
       source_value
       29SB            2
       25FG            2
       35DE            1
       31DE            1
       dtype: int64
 

Ответ №3:

Использование левого слияния с индикатором для идентификации только в клиенте

 In[]: merge_df = client_df.merge(source_df, how='left', indicator=True)
      merge_df[merge_df['_merge']=='left_only'].groupby('source_value').size()

Out[]:
    source_value
    25FG    2
    29SB    2
    31DE    1
    35DE    1
 

Ответ №4:

 
client_df.groupby('source_value')['source_value'].count().loc[pd.Index(client_df.source_value).difference(source_df.source_value)]