首页 > 解决方案 > 比较 2 个相似数据框的差异的更快方法

问题描述

这延续了我之前的问题: 如何在比较相同数据框的 2 个版本后获取修改后的行

我现在完成了修改,但是,我使用下面的方法来查找插入和删除。它工作正常,但是需要很多时间。通常用于具有 10 列和 10M 行的 CSV 文件。

对于我的问题,INSERT 是不在旧文件中的记录,而是在新文件中。DELETE 是旧文件中的记录,而不是新文件中的记录。

下面是代码:

def getInsDel(df_old,df_new,key):
    #concatinating old and new data to generate comparisons
    df = pd.concat([df_new,df_old])
    df= df.reset_index(drop = True)


    #doing a group by for getting the frequency of each key
    print('Grouping data for frequency of key...')
    df_gpby = df.groupby(list(df.columns))
    idx = [x[0] for x in df_gpby.groups.values() if len(x) == 1]
    df_delta = df.reindex(idx)
    df_delta_freq = df_delta.groupby(key).size().reset_index(name='Freq')

    #Filtering data for frequency = 1, since these will be the target records for DELETE and INSERT 
    print('Creating data frame to get records with Frequency = 1  ...')
    filter = df_delta_freq['Freq']==1
    df_delta_freq_ins_del = df_delta_freq.where(filter)


    #Dropping row with NULL
    df_delta_freq_ins_del = df_delta_freq_ins_del.dropna()


    print('Creating data frames of Insert and Deletes  ...')
    #Creating INSERT dataFrame 
    df_ins = pd.merge(df_new, 
                     df_delta_freq_ins_del[key],
                     on = key,
                     how = 'inner'
                    )

    #Creating DELETE dataFrame
    df_del = pd.merge(df_old, 
                     df_delta_freq_ins_del[key],
                     on = key,
                     how = 'inner'
                    )

    print('size of INSERT file: ' + str(df_ins.shape))
    print('size of DELETE file: ' + str(df_del.shape))


    return df_ins,df_del

我对每个键的频率进行分组的部分,大约需要总时间的 80%,所以对于我的 CSV,大约需要 12-15 分钟。

必须有更快的方法来做到这一点?

供您参考,以下是我的预期结果:

例如,旧数据是:

ID  Name  X  Y
1   ABC   1  2
2   DEF   2  3
3   HIJ   3  4

新的数据集是:

ID  Name   X   Y
2   DEF    2   3
3   HIJ    55  42
4   KLM    4   5

其中 ID 是密钥。

Insert_DataFrame 应该是:

ID   Name   X   Y
4    KLM    4   5

Deleted_DataFrame 应该是:

ID   Name   X   Y
1    ABC    1   2

标签: pythonpandasdataframe

解决方案


被删除

delete=pd.merge(old,new,how='left',on='ID',indicator=True)
delete=delete.loc[delete['_merge']=='left_only']
delete.dropna(1,inplace=True)

被插入

insert=pd.merge(new,old,how='left',on='ID',indicator=True)
insert=insert.loc[insert['_merge']=='left_only']
insert.dropna(1,inplace=True)

推荐阅读