2017-03-01 226 views
1

我试图将一个长格式df与多个索引转换为一个宽格式的df。为什么df_in.pivot()失败和/或为什么pd.pivot_table返回含有奇怪分层索引的结果,这样我就无法访问我想要投射的列?熊猫df.pivot()和pd.pivot_table()与多个索引

# input table 
df_in = pd.DataFrame({'idx1':range(2)*4, 'idx2':['a']*4+['b']*4, 'field': ['f1']*2+['f2']*2+['f1']*2+['f2']*2, 'value': np.array(range(2)*4)*2+1}) 
''' 
    field idx1 idx2 value 
0 f1  0 a  1 
1 f1  1 a  3 
2 f2  0 a  1 
3 f2  1 a  3 
4 f1  0 b  1 
5 f1  1 b  3 
6 f2  0 b  1 
7 f2  1 b  3 
''' 

# want something like this 
pd.DataFrame({'idx1':range(2)*2, 'idx2': ['a']*2+['b']*2, 'a':[1,3]*2, 'b':[1,3]*2}) 
''' 
    a b idx1 idx2 
0 1 1  0 a 
1 3 3  1 a 
2 1 1  0 b 
3 3 3  1 b 
''' 

#doesn't work => ValueError: all arrays must be same length 
df_in.pivot(index=['idx1','idx2'], columns =['field']) 

#doesn't work => weird hierarchical index 
pd.pivot_table(df_in, index=['idx1','idx2'], columns =['field']) 

''' 
      value 
field  f1 f2 
idx1 idx2   
0 a  1 1 
    b  1 1 
1 a  3 3 
    b  3 3 
''' 
# doesn't work => KeyError: 'f1' 
pd.pivot_table(df_in, index=['idx1','idx2'], columns =['field'])['f1'] 

# doesn't work => KeyError: 'f1' 
pd.pivot_table(df_in, index=['idx1','idx2'], columns =['field']).reset_index()['f1'] 

回答

1

为了避免多级柱,明确作为一个字符串,而不是一个列表就足够了指定的值列:

df_in.pivot_table(values='value', index=['idx1', 'idx2'], columns='field').reset_index() 

#field idx1 idx2 f1 f2 
#0  0  a 1 1 
#1  0  b 1 1 
#2  1  a 3 3 
#3  1  b 3 3 

如果你有多层列,您可以使用元组来访问它们,例如:

df_out = df_in.pivot_table(values=['value'], index=['idx1', 'idx2'], columns='field') 

给出了一个具有多级列的数据框,以访问f1栏,你可以这样做:

df_out[('value', 'f1')] 

给出:

#idx1 idx2 
#0  a  1 
#  b  1 
#1  a  3 
#  b  3 
#Name: (value, f1), dtype: int64