【问题标题】:How to calculate percentage difference between two data frames with Pandas?如何使用 Pandas 计算两个数据帧之间的百分比差异?
【发布时间】:2019-08-12 20:10:44
【问题描述】:

我正在使用pandas,并执行了一些计算和转换,最终得到两个看起来或多或少像这样的数据框:

ID      'abc'     'def'
Total     4         5
Slow      0         0
Normal    1         2
Fast      3         3

ID      'abc'     'def'
Total     3         4
Slow      0         0
Normal    0         1
Fast      3         3

现在,给定这两个数据帧,我想生成第三个数据帧,它以某种方式返回第二个数据帧占第一个数据帧的百分比。这样我希望结果是这样的:

ID      'abc'     'dfe'
Total   75.0%      80.0%
Slow     None      None
Normal   0.0%      50.0%
Fast    100.0%     100.0%

如果第一个数据帧中有 0,那么在生成的数据帧中,我们将该单元格设置为 None 或其他值。整个想法是,最后我会将结果写入 Excel 文件,因此我希望在 Excel 中具有None 的单元格为空。任何想法如何使用pandas 在 Python 中执行此操作?

【问题讨论】:

    标签: python pandas dataframe percentage calculation


    【解决方案1】:

    您可以在感兴趣的列上简单地将df2 除以df1

    df2.loc[:,"'abc'":] = df2.loc[:,"'abc'":].div(df1.loc[:,"'abc'":]).mul(100)
    
         ID     'abc'  'dfe'
    0   Total   75.0   80.0
    1    Slow    NaN    NaN
    2  Normal    0.0   50.0
    3    Fast  100.0  100.0
    

    更新

    为了指定格式,你可以这样做:

    df2.loc[:,"'abc'":] = df2.where(df2.loc[:,"'abc'":].isna(), 
                                    df2.round(2).astype(str).add('%'))
    
          ID    'abc'   'dfe'
    0   Total   75.0%   80.0%
    1    Slow     NaN     NaN
    2  Normal    0.0%   50.0%
    3    Fast  100.0%  100.0%
    

    由于没有小数位,除了.0round(2) 对显示的浮点数没有影响,但是一旦除法后有更多小数位的浮点数,你会看到@987654327 @ 所有浮点数的小数位。

    【讨论】:

    • 这就是答案,简短而简单。
    • 谢谢,但是当写入 excel 时,这会返回许多小数或不返回小数。我需要始终保留 2 位小数。另外,我怎样才能包含 % 符号?
    • 更新了答案@terett
    • 这似乎为我提供了 nan% 的 NaN 值。
    • 现在检查@terett
    【解决方案2】:

    Pandas 提供了一些直接指定styling in the output excel file 的可能性。它是有限的,但幸运的是你确实包含了一个数字格式选项。

    import pandas as pd
    
    # Initialize example dataframes
    df1 = pd.DataFrame(
        data=[[4, 5], [0, 0], [1, 2], [3, 3], [3, 3]],
        index=['Total', 'Slow', 'Normal', 'Fast', 'Fast'],
        columns=['abc', 'def'],
    )
    df2 = pd.DataFrame(
        data=[[3, 4], [0, 0], [0, 1], [3, 3], [3, 3]],
        index=['Total', 'Slow', 'Normal', 'Fast', 'Fast'],
        columns=['abc', 'def'],
    )
    
    result_df = df2 / df1
    
    # Change rows index into data column (to avoid any chance of having non-unique row index values,
    # since the pandas styler can only handle unique row index)
    result_df = result_df.reset_index()
    
    # Write excel output file with number format styling applied
    result_df.style.applymap(lambda _: 'number-format: 0.00%').to_excel('result.xlsx', engine='openpyxl', index=False)
    

    【讨论】:

    • 感谢您的回答。这会在我这边引发错误:ValueError: style is not supported for non-unique indices.
    • 我正在使用xlsxwriter 引擎。
    • @terett 如果您完全按照此处给出的方式运行完整的代码示例(即包括df1df2 定义语句),是否会出现ValueError
    • 那是因为我的场景比较复杂,我编辑了数据框的index
    • @terett excel 引擎似乎没有什么不同。选项 engine=openpyxlengine=xlsxwriter 生成相同的 excel 文件(至少在我尝试时)。
    猜你喜欢
    • 1970-01-01
    • 2022-11-29
    • 2021-12-24
    • 1970-01-01
    • 1970-01-01
    • 2021-11-24
    • 2020-10-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多