【问题标题】:pandas: create pivot table by two different dimensions?熊猫:通过两个不同的维度创建数据透视表?
【发布时间】:2016-07-25 19:09:01
【问题描述】:

我是熊猫新手。我有一个赞助商和公司参加的考试数据框:

import pandas pd

df = pd.DataFrame({
  'sponsor': ['A71991', 'A71991', 'A71991', 'A81001', 'A81001'],
  'sponsor_class': ['Industry', 'Industry', 'Industry', 'NIH', 'NIH'],
  'year': [2012, 2013, 2013, 2012, 2013],
  'passed': [True, False, True, True, True],
})

现在我想输出一个 CSV 文件,其中包含每个赞助商及其类别的行,以及按年份的通过率和总率的列:

sponsor,sponsor_class,2012_total,2012_passed,2013_total,2013_passed
A71991,Industry,1,1,2,1
A81001,NIH,1,1,1,1

如何从df 获取到这个重组的数据框?我想我需要按sponsorsponsor_class 分组,然后转出总计数,以及passed 的计数是True 按年份,然后展平这些列。 (我知道我以 pd.write_csv(mydf) 结尾。)

我试过从这个开始:

df_g = df.groupby(['sponsor', 'sponsor_class', 'year', 'passed'])

但这给了我一个空的数据框。

我想我需要一个数据透视表来透视年份并传递状态...但我不知道从哪里开始。

更新:到达某处:

df_g = df_completed.pivot_table(index=['lead_sponsor', 'lead_sponsor_class'], 
                                columns='year', 
                                aggfunc=len, fill_value=0)
df_g[['passed']]

现在我需要解决 (1) 如何获取所有行以及 passed 的计数,以及 (2) 如何取消嵌套 CSV 文件的列。

【问题讨论】:

    标签: python pandas


    【解决方案1】:
    # set index to prep for unstack
    df1 = df.set_index(['sponsor', 'sponsor_class', 'year']).astype(int)
    
    # groupby all the stuff in the index
    gb = df1.groupby(level=[0, 1, 2]).passed
    
    # use agg to get sum and count    
    # swaplevel and sort_index to get stuff sorted out
    df2 = gb.agg({'passed': 'sum', 'total': 'count'}) \
              .unstack().swaplevel(0, 1, 1).sort_index(1)
    
    # collapse multiindex into index
    df2.columns = df2.columns.to_series().apply(lambda x: '{}_{}'.format(*x))
    
    print df2.reset_index().to_csv(index=None)
    
    
    sponsor,sponsor_class,2012_passed,2012_total,2013_passed,2013_total
    A71991,Industry,1,1,1,2
    A81001,NIH,1,1,1,1
    

    【讨论】:

      【解决方案2】:

      我可以通过几个步骤了解如何做到这一点:

      import numpy as np, pandas as pd
      df['total'] = df['passed'].astype(int)
      ldf = pd.pivot_table(df,index=['sponsor','sponsor_class'],columns='year',
                           values=['total'],aggfunc=len) # total counts
      rdf = pd.pivot_table(df,index=['sponsor','sponsor_class'],columns='year',
                           values=['total'],aggfunc=np.sum) # number passed 
      cdf = pd.concat([ldf,rdf],axis=1) # combine horizontally
      cdf.columns = cdf.columns.get_level_values(0) # flatten index
      cdf.reset_index(inplace=True)
      columns = ['sponsor','sponsor_class']
      yrs = sorted(df['year'].unique())
      columns.extend(['{}_total'.format(yr) for yr in yrs])
      columns.extend(['{}_passed'.format(yr) for yr in yrs])
      cdf.columns = columns
      

      结果:

      >>> cdf
        sponsor sponsor_class  2012_total  2013_total  2012_passed  2013_passed
      0  A71991      Industry           1           2            1            1
      1  A81001           NIH           1           1            1            1
      

      最后:

      cdf.to_csv('/path/to/file.csv',index=False)
      

      【讨论】:

        猜你喜欢
        • 2016-05-27
        • 2021-02-28
        • 2023-01-11
        • 1970-01-01
        • 2022-11-26
        • 2016-01-05
        • 2019-04-24
        • 2017-01-14
        相关资源
        最近更新 更多