比较两个熊猫数据帧上的所有列以获得差异

时间:2019-02-05 13:14:36

标签: python pandas dataframe

我有两个熊猫数据框。可以说第一个是master

ID  COL1    COL2
1   A       AA
2   B       BB
3   C       CC
4   D       DD

另外一个source

ID  COL1    COL2
1   A       ZZ
2   B       BB
3   YY      CC
5   G       GG
6   H       HH

显然,长度可以不同,并且差异可以超过一列。但是,结构将相同。我想在source中找到新记录,或者与master中可用的记录不同。也就是说,我正在寻找的输出是一个数据帧:

ID  COL1    COL2
1   A       ZZ
3   YY      CC
5   G       GG
6   H       HH

我尝试了以下解决方案:

但是这些似乎都不对我有用。基本上,这是在尝试找出新功能。

3 个答案:

答案 0 :(得分:2)

您可以创建遮罩并使用boolean indexing

# set index
source = source.set_index('ID')
master = master.set_index('ID')

# find any record across rows where source is not in master
mask = (~source.isin(master)).any(1)
# boolean indexing
source[mask]

   COL1 COL2
ID          
1     A   ZZ
3    YY   CC
5     G   GG
6     H   HH

答案 1 :(得分:1)

mergeindicator=Trueouter join一起使用,然后按df2.columns过滤并仅获取列:

#specified columns in list
cols = ['COL1','COL2']
#all columns without ID
#cols = df.columns.difference(['ID'])
df = (df1.merge(df2, on=cols, how='outer', indicator=True, suffixes=('_',''))
         .query("_merge == 'right_only'")[df2.columns])
print (df)
    ID COL1 COL2
4  1.0    A   ZZ
5  3.0   YY   CC
6  5.0    G   GG
7  6.0    H   HH

答案 2 :(得分:1)

有几种方法可以解决此问题,具体取决于您处理内存分配的方式以及打算使用大型数据集还是仅出于学术/培训目的。

  1. 迭代比较,然后将它们附加到新的数据框中。 (更多代码,更有效的存储方式)
  2. 创建一个新的合并(外部)数据框,并应用一个函数来删除重复项。 (代码较少,但内存效率较低)

这些只是两个主意,但可能还有更多主意,仅是为了提供一个见解。

解决方案1 ​​:(考虑到ID是唯一的而不是索引)

list = source['ID'].tolist() #get a list of all the ids in source
results = pd.DataFrame(columns = source.columns.tolist()) #Creates an empty df with same columns
for id in list:
    if(~((source[id]['COL1'] == master[id]['COL1']) & (source[id]['COL2'] == master[id]['COL2']))):
    #Here we evaluate the cases where everything is equal and execute on negation of said statement (by using ~, which equates to NOT)
        results.append(source[id])

解决方案2:

results = source.merge(master, how = 'outer', on= source.columns.tolist()) #assuming both dfs have same columns
final_results = results.drop_duplicates(Keep = False) #this will drop all rows that are duplicated.
相关问题