【问题标题】:Compare two Excel files that have a different number of rows using Python Pandas使用 Python Pandas 比较具有不同行数的两个 Excel 文件
【发布时间】:2023-04-10 11:31:03
【问题描述】:

我使用的是 Python 3.7,我想比较两个具有相同列(140 列)但行数不同的 Excel 文件,我查看了网站,但没有找到解决方案我的情况!

这是一个例子:

df1 (old report) : 

id       qte     d1    d2

A        10      23    35  

B        43      63    63

C       15       61    62

df2 (new report) : 

id       qte     d1    d2

A        20      23    35  

C       15       61    62

E       38       62    16

F       63       20    51

结果应该是:

  • 修改行必须为黄色,修改后的值必须为红色

  • 绿色的新行

  • 红色为删除的行

    id qte d1 d2

    A 20 23 35

    C 15 61 62

    B 43 63 63

    E 38 62 16

    F 63 20 51

代码:

import pandas as pd
import numpy as np

df1= pd.read_excel(r'C .....\data novembre.xlsx','Sheet1',na_values=['NA'])
df2= pd.read_excel(r'C.....\data decembre.xlsx','Sheet1',na_values=['NA'])
merged_data=df1.merge(df2, left_on = 'id', right_on = 'id', how = 'outer')

加入数据虽然不是我想要的!

我刚开始学习 Python,所以我真的需要帮助!

【问题讨论】:

    标签: pandas numpy python-3.7


    【解决方案1】:

    excel diff 可以很快变成一个时髦的野兽,但我们应该能够通过一些 concats 和布尔语句来做到这一点。

    假设您的数据框被称为df1, df2

    df1 = df1.set_index('id')
    df2 = df2.set_index('id')
    
    df3 = pd.concat([df1,df2],sort=False)
    df3a = df3.stack().groupby(level=[0,1]).unique().unstack(1).copy()
    
    
    df3a.loc[~df3a.index.isin(df2.index),'status'] = 'deleted' # if not in df2 index then deleted
    df3a.loc[~df3a.index.isin(df1.index),'status'] = 'new'     # if not in df1 index then new
    idx = df3.stack().groupby(level=[0,1]).nunique() # get modified cells. 
    df3a.loc[idx.mask(idx <= 1).dropna().index.get_level_values(0),'status'] = 'modified'
    df3a['status'] = df3a['status'].fillna('same') # assume that anything not fufilled by above rules is the same.
    

    print(df3a)
    
          d1    d2       qte    status
    id                                
    A   [23]  [35]  [10, 20]  modified
    B   [63]  [63]      [43]   deleted
    C   [61]  [62]      [15]      same
    E   [62]  [16]      [38]       new
    F   [20]  [51]      [63]       new
    

    如果您不介意将所有数据类型转换为字符串对性能的影响,那么这可能会起作用。不过我不推荐它,使用事实或缓慢变化的维度架构来保存此类数据,将来您会感谢自己的。

    df3a.stack().explode().astype(str).groupby(level=[0,1]).agg('-->'.join).unstack(1)
    
        d1  d2      qte    status
    id                           
    A   23  35  10-->20  modified
    B   63  63       43   deleted
    C   61  62       15      same
    E   62  16       38       new
    F   20  51       63       new
    

    【讨论】:

    • 1000 感谢你,它可以工作了!,我还有一个问题,如果我想用绿色突出显示新行,用红色突出删除的行,而对于修改后的行,它将用黄色突出显示(对于修改后的值,我只会将新值保留在数组中),我该怎么做?
    • @FaziaChenna 没问题 :) 在这里看到这个 pandas.pydata.org/pandas-docs/stable/user_guide/style.html 我很擅长 Pandas 的造型
    • 是的,我明白了,谢谢,在之前的结果中,(d1 d2 和 qte)的位置发生了变化,应该是这样的:id qte d1 d2。我怎样才能拥有相同的列结构
    • @FaziaChenna 您可以通过手动指定 cols df3a[df1.columns] 来设置它应该可以工作。不要忘记接受答案:)
    • 我没有得到我想要的结果,问题是我的原始文件有超过 140 列,我应用代码时它不起作用!
    猜你喜欢
    • 1970-01-01
    • 2014-05-27
    • 2020-10-17
    • 2016-12-15
    • 1970-01-01
    • 2019-06-27
    • 2019-02-10
    • 2018-06-26
    • 2020-12-11
    相关资源
    最近更新 更多