2015-10-07 88 views
5

堆叠熊猫DataFrame时,返回Series。通常在堆叠DataFrame之后,我将它转换回DataFrame。但是,来自堆叠数据的默认名称使得重命名这些列有点难以理解。我正在寻找的是一种更容易/内置的方式,可以在堆叠后为列提供明智的名称。堆叠熊猫时设置列名DataFrame

例如,以下DataFrame

In [64]: df = pd.DataFrame({'id':[1,2,3], 
    ...:     'date':['2015-09-31']*3, 
    ...:     'value':[100, 95, 42], 
    ...:     'value2':[200, 57, 27]}).set_index(['id','date']) 

In [65]: df 
Out[65]: 
       value value2 
id date      
1 2015-09-31 100  200 
2 2015-09-31  95  57 
3 2015-09-31  42  27 

我叠,并将其转换回DataFrame像这样:

In [68]: df.stack().reset_index() 
Out[68]: 
    id  date level_2 0 
0 1 2015-09-31 value 100 
1 1 2015-09-31 value2 200 
2 2 2015-09-31 value 95 
3 2 2015-09-31 value2 57 
4 3 2015-09-31 value 42 
5 3 2015-09-31 value2 27 

所以为了适当命名这些列我需要做的像这样:

In [72]: stacked = df.stack() 

In [73]: stacked 
Out[73]: 
id date    
1 2015-09-31 value  100 
       value2 200 
2 2015-09-31 value  95 
       value2  57 
3 2015-09-31 value  42 
       value2  27 
dtype: int64 

In [74]: stacked.index.set_names('var_name', level=len(stacked.index.names)-1, inplace=True) 

In [88]: stacked.reset_index().rename(columns={0:'value'}) 
Out[88]: 
    id  date var_name value 
0 1 2015-09-31 value 100 
1 1 2015-09-31 value2 200 
2 2 2015-09-31 value  95 
3 2 2015-09-31 value2  57 
4 3 2015-09-31 value  42 
5 3 2015-09-31 value2  27 

理想情况下,该解决方案将是这个样子:

df.stack(new_index_name='var_name', new_col_name='value') 

但看docs它看起来并不像stack采取任何这样的论点。熊猫有更容易/内置的方式来处理这个工作流程吗?

回答

5

pd.melt对于将DataFrames从“wide”格式转换为“long”格式通常很有用。你可以在这里使用pd.melt如果先转换iddate指数水平列:

In [56]: pd.melt(df.reset_index(), id_vars=['id', 'date'], value_vars=['value', 'value2'], var_name='var_name', value_name='value') 
Out[56]: 
    id  date var_name value 
0 1 2015-09-31 value 100 
1 2 2015-09-31 value  95 
2 3 2015-09-31 value  42 
3 1 2015-09-31 value2 200 
4 2 2015-09-31 value2  57 
5 3 2015-09-31 value2  27 
+1

+1,但是阐述的一点点的将是理想的。也许资本会开始列名,因为我对这么多“价值”感到困惑。 – josh

7

所以这里有一种方法,你可能会发现一点点清洁,使用事实columnsSeries也可以携带的名称。

In [45]: df 
Out[45]: 
       value value2 
id date      
1 2015-09-31 100  200 
2 2015-09-31  95  57 
3 2015-09-31  42  27 

In [46]: df.columns.name = 'var_name' 

In [47]: s = df.stack() 

In [48]: s.name = 'value' 

In [49]: s.reset_index() 
Out[49]: 
    id  date var_name value 
0 1 2015-09-31 value 100 
1 1 2015-09-31 value2 200 
2 2 2015-09-31 value  95 
3 2 2015-09-31 value2  57 
4 3 2015-09-31 value  42 
5 3 2015-09-31 value2  27