【问题标题】:Dividing multiindex columns by sum to create percentages将多索引列除以总和以创建百分比
【发布时间】:2014-10-21 06:06:20
【问题描述】:

我有一个从数据透视表创建的数据框,看起来类似于:

import pandas as pd
d = {('company1', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0},
('company1', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0},
('company1', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0},
('company2', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0},
('company2', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0},
('company2', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0},}

df = pd.DataFrame(d)

                company1    company2
                FN  FP  TP  FN  FP  TP
April- 2012     112 0   0   112 0   0
April- 2013     370 544 140 370 544 140
April- 2014     499 50  24  499 50  24
August- 2012    431 0   0   431 0   0
August- 2013    496 0   0   496 0   0
August- 2014    221 426 77  221 426 77

我希望在多索引列的上层进行迭代,以将每个公司除以其总和来创建一个百分比:

                company1     company2
                FN  FP  TP   FN    FP   TP
April- 2012     1   0   0    1   0  0
April- 2013     .35 .51 .13  .35   .51  .13
April- 2014     .87 .09 .03  .87   .09  .03
etc.

我事先不知道公司名称。这是昨天提出的问题的变体:Summing multiple columns with multiindex columns

【问题讨论】:

  • 只除以昨天答案的结果吗?
  • 是的,这就是问题所在。如何做到这一点?我不知道如何在不产生错误的情况下排列它们。

标签: python pandas


【解决方案1】:

您可以使用div 方法除以总和(您可以指定要匹配的级别):

df.div(df.sum(axis=1, level=0), level=0)

【讨论】:

  • 这绝对是完美的。再次感谢!
【解决方案2】:

虽然 joris 的解决方案效果很好,但我想补充一点,一旦 Multiindex 有更多级别,这将无法正常工作。这是我部分基于 StackOverflow 帖子 (Normalize DataFrame by group) 和 Pandas 文档 (http://pandas.pydata.org/pandas-docs/stable/groupby.html) 的解决方案。

d = {
('X', 'company1', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0},
('X', 'company1', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0},
('X', 'company1', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0},
('X', 'company2', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0},
('X', 'company2', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0},
('X', 'company2', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0},
('Y','company1', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0},
('Y','company1', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0},
('Y','company1', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0},
('Y','company2', 'False Negative'): {'April- 2012': 112.0, 'April- 2013': 370.0, 'April- 2014': 499.0, 'August- 2012': 431.0, 'August- 2013': 496.0, 'August- 2014': 221.0},
('Y','company2', 'False Positive'): {'April- 2012': 0.0, 'April- 2013': 544.0, 'April- 2014': 50.0, 'August- 2012': 0.0, 'August- 2013': 0.0, 'August- 2014': 426.0},
('Y','company2', 'True Positive'): {'April- 2012': 0.0, 'April- 2013': 140.0, 'April- 2014': 24.0, 'August- 2012': 0.0, 'August- 2013': 0.0,'August- 2014': 77.0},
}

df = pd.DataFrame(d)
# extrapolation of original method: not working!
# df.div(df.sum(axis=1,level=[0,1]), level=[0,1]) #  does not work

# alternative 1: replicating the sums for each company to fit the number of columns using numpy
df.div(np.repeat(df.sum(axis=1,level=[0,1]).values, 3, axis=1), axis=1)

# alternative 2: stacking, grouping, transforming and unstacking
df.columns.names = ['top', 'company', 'result'] # naming column levels for convenience 
df.\
    stack(["top", "company", "result"]).\
    groupby(level=[0,1,2]).\
    transform(lambda x: (x / x.sum(axis=0))).\
    unstack(["top", "company", "result"])

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-14
    • 1970-01-01
    • 1970-01-01
    • 2022-06-24
    • 2013-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多