使用计数和比例将分类变量的 Pandas DataFrame 转换为 MultiIndex

tom*_*omp 3 python dataframe pandas categorical-data

我有一个包含多个分类变量的 Pandas DataFrame。例如:

import pandas as pd

d = {'grade':['A','B','C','A','B'], 
    'year':['2013','2013','2013','2012','2012']}

df = pd.DataFrame(d)
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

我想将其转换为具有以下属性的 MultiIndex DataFrame:

  • 第一级索引是变量名(例如'grade')
  • 二级索引是变量内的级别(例如“A”、“B”、“C”)
  • 一列包含“n”,该级别出现的次数的计数
  • 第二列包含“比例”,即该级别表示的比例。

例如:

在此处输入图片说明

任何人都可以建议一种创建此 MultiIndex DataFrame 的方法吗?

Sco*_*ton 5

您可以使用meltand执行此操作的另一种方法groupby

df_out = df.melt().groupby(['variable','value']).size().to_frame(name='n')
df_out['proportion'] = df_out['n'].div(df_out.n.sum(level=0),level=0)
print(df_out)
Run Code Online (Sandbox Code Playgroud)

输出:

                n  proportion
variable value               
grade    A      2         0.4
         B      2         0.4
         C      1         0.2
year     2012   2         0.4
         2013   3         0.6
Run Code Online (Sandbox Code Playgroud)

而且,如果您真的想发疯并在单行中做到这一点:

(df.melt().groupby(['variable','value']).size().to_frame(name='n')
  .pipe(lambda x: x.assign(proportion = x[['n']]/x.groupby(level=0).transform('sum'))))
Run Code Online (Sandbox Code Playgroud)

使用@Wen pct 计算的升级解决方案:

(df.melt().groupby(['variable','value']).size().to_frame(name='n')
  .pipe(lambda x: x.assign(proportion = x['n'].div(x.n.sum(level=0),level=0))))
Run Code Online (Sandbox Code Playgroud)