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

问题描述 投票:3回答:4

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

import pandas as pd

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

df = pd.DataFrame(d)

enter image description here

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

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

例如:

enter image description here

有人可以建议一种创建这个MultiIndex DataFrame的方法吗?

python pandas dataframe categorical-data
4个回答
3
投票

另一种方法可以使用meltgroupby

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)

输出:

                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

并且,如果你真的想变得疯狂并且在单行中做:

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

使用@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))))

3
投票

你可以尝试这个..

df1=df.apply(pd.value_counts).stack().swaplevel(0,1).to_frame('n')
df1['pct']=df1['n'].div(df1.n.sum(level=0),level=0)
df1
Out[89]: 
              n  pct
year  2012  2.0  0.4
      2013  3.0  0.6
grade A     2.0  0.4
      B     2.0  0.4
      C     1.0  0.2

1
投票

Stey by step方法:

df1 = df.groupby("grade").count()
df2 = df.groupby("year").count() 

df1.columns = ['n']
df2.columns = ['n']
df1['proportion'] = df1.divide(df1.sum())
df2['proportion'] = df2.divide(df2.sum())

df_new = pd.concat([df1, df2], keys=['grade', 'year'], names=['variable'])
  • 使用concat时,可以指定keys作为最外层索引。同时使用names=为此新索引指定名称。

enter image description here


0
投票

可以通过在循环中堆叠每个变量来创建DataFrame,但这似乎效率低下。例如。:

d_end = []
for c in df.columns:
    temp_df = pd.DataFrame(df[c].value_counts().rename('n'))
    temp_df['proportion'] = temp_df['n'] / temp_df['n'].sum()
    temp_df['variable'] = c
    temp_df.set_index(['variable',temp_df.index],inplace=True)
    d_end.append(temp_df)

df_end = pd.concat(d_end,axis=0)

我希望有人可以建议一个更好的方法,避免循环。

© www.soinside.com 2019 - 2024. All rights reserved.