如何计算带有行标题和列标题的 python 数据透视表的行百分比和列百分比?

how to calculate % of row and % of column for a python pivot with row and column headings?

对于这个简单的数据透视表,如何将值转换为行的百分比,以及列的百分比?

import pandas as pd
df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
                   'B' : ['A', 'B', 'C'] * 4,
               'C' : range(12)})
pd.pivot_table(df, index='A', columns='B', aggfunc=sum)

不知何故,经过一番搜索后,我没有找到这个简单问题的答案。

预期结果(如果得到列的百分比)

      A   B  C
ONE   50% 24% 50%
THREE 13% 31% 42%
TWO  36% 45% 8%

谢谢

您可以使用 pd.crosstab:

获得所需的输出
import numpy as np
import pandas as pd

df = pd.DataFrame({'A' : ['one', 'one', 'two', 'three'] * 3,
                   'B' : ['A', 'B', 'C'] * 4,
               'C' : range(12)})

pd.crosstab(df.A, df.B, values=df.C, aggfunc=np.sum, normalize='columns')

这应该产生:

B             A         B         C
A                                  
one    0.500000  0.227273  0.500000
three  0.166667  0.318182  0.423077
two    0.333333  0.454545  0.076923

您可以重新格式化输出以显示百分比 applymap:

pd.crosstab(df.A, df.B,values=df.C,aggfunc=np.sum,normalize='columns').applymap(lambda x: "{0:.0f}%".format(100*x))

这应该产生:

B        A    B    C
A                   
one    50%  23%  50%
three  17%  32%  42%
two    33%  45%   8%

编辑:

如果normalize参数不起作用,你可以用apply得到百分比:

pd.crosstab(df.A, df.B, values=df.C, aggfunc=np.sum).apply(lambda x: x/x.sum()).applymap(lambda x: "{:.0f}%".format(100*x))

希望这有用。

这会给你想要的结果

df = pd.pivot_table(df, index='A', columns='B', values = 'C', aggfunc=sum).apply(lambda x:100 * x / float(x.sum())).round(2)

我已经把它作为一个衬垫完成了,但你可以分解枢轴并应用

你得到

          A      B       C
  A         
 one    50.00   22.73   50.00
 three  16.67   31.82   42.31
 two    33.33   45.45   7.69

使用pandas.crosstab,您可以非常轻松地实现您的需求。

请注意,规范化 可以根据您的需要按列或按行。

pandas.crosstab(index=df['A'],columns=[df['A'], df['B'], df['C']],normalize='columns')
pandas.crosstab(index=df['A'],columns=[df['A'], df['B'], df['C']],normalize='rows')