2016-07-25 49 views
4

我是熊貓新手。我有贊助商,公司採取考試的數據幀:熊貓:通過兩個不同的維度創建數據透視表?

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進行分組,然後將總計數和每年passedTrue的計數轉出,然後平滑這些列。 (我知道我有pd.write_csv(mydf)結束。)

我試着開始與此:

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

但是,這給了我一個空的數據幀。

我想我需要一個數據透視表來轉換年份並傳遞狀態......但我不知道從哪裏開始。

UPDATE:取得了一些進展:

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文件的列。

回答

2
# 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 
+0

這是驚人的,謝謝! – Richard

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)