DataFrame列名称中包含的属性/信息

时间:2015-08-04 05:06:45

标签: python pandas

我有一些从csv导入的数据,用于创建类似我用过的东西:

data = pd.DataFrame([[1,0,2,3,4,5],[0,1,2,3,4,5],[1,1,2,3,4,5],[0,0,2,3,4,5]], columns=['split','sex', 'group0Low', 'group0High', 'group1Low', 'group1High'])
means = data.groupby(['split','sex']).mean()

所以数据框看起来像这样:

           group0Low  group0High  group1Low  group1High
split sex                                              
0     0            2           3          4           5
      1            2           3          4           5
1     0            2           3          4           5
      1            2           3          4           5

您会注意到每列实际上包含2个变量(组#和高度)。 (这是为了在SPSS中运行重复测量anova而设置的。)

我想把列分开,所以我也可以像这样分组“群组”(我实际上搞砸了数字的顺序,但希望这个想法很清楚):

            low high
split   sex group       
    0   0   95  265
0   0   1   123 54
    1   0   120 220
    1   1   98  111
1   0   0   150 190
    0   1   211 300
    1   0   139 86
    1   1   132 250

我如何实现这一目标?

2 个答案:

答案 0 :(得分:1)

这可以通过首先在列名上构建多级索引,然后按stack重新整形数据框来完成。

import pandas as pd
import numpy as np

# some artificial data
# ==================================
multi_index = pd.MultiIndex.from_arrays([[0,0,1,1], [0,1,0,1]], names=['split', 'sex'])
np.random.seed(0)
df = pd.DataFrame(np.random.randint(50,300, (4,4)), columns='group0Low group0High group1Low group1High'.split(), index=multi_index)
df

           group0Low  group0High  group1Low  group1High
split sex                                              
0     0          222          97        167         242
      1          117         245        153          59
1     0          261          71        292          86
      1          137         120        266         138

# processing
# ==============================

level_group = np.where(df.columns.str.contains('0'), 0, 1)
# output: array([0, 0, 1, 1])
level_low_high = np.where(df.columns.str.contains('Low'), 'low', 'high')
# output: array(['low', 'high', 'low', 'high'], dtype='<U4')

multi_level_columns = pd.MultiIndex.from_arrays([level_group, level_low_high], names=['group', 'val'])
df.columns = multi_level_columns
df.stack(level='group')

val              high  low
split sex group           
0     0   0        97  222
          1       242  167
      1   0       245  117
          1        59  153
1     0   0        71  261
          1        86  292
      1   0       120  137
          1       138  266

答案 1 :(得分:1)

第一个技巧是使用stack

将列收集到一个列中
In [6]: means
Out[6]: 
           group0Low  group0High  group1Low  group1High
split sex                                              
0     0            2           3          4           5
      1            2           3          4           5
1     0            2           3          4           5
      1            2           3          4           5

In [13]: stacked = means.stack().reset_index(level=2)
In [14]: stacked.columns = ['group_level', 'mean']
In [15]: stacked.head(2)
Out[15]: 
          group_level  mean
split sex                  
0     0     group0Low     2
      0    group0High     3

现在我们可以使用pd.Series.strgroup_level上执行我们想要的任何字符串操作,如下所示:

In [18]: stacked['group'] = stacked.group_level.str[:6]
In [21]: stacked['level'] = stacked.group_level.str[6:]
In [22]: stacked.head(2)
Out[22]: 
          group_level  mean   group level
split sex                                
0     0     group0Low     2  group0   Low
      0    group0High     3  group0  High

现在你在做生意,你可以做任何你想做的事。例如,对每个组/级别求和:

In [31]: stacked.groupby(['group', 'level']).sum()
Out[31]: 
              mean
group  level      
group0 High     12
       Low       8
group1 High     20
       Low      16

如何按所有内容进行分组?

如果您想按splitsexgroup level进行分组,您可以这样做:

In [113]: stacked.reset_index().groupby(['split', 'sex', 'group', 'level']).sum().head(4)
Out[113]: 
                        mean
split sex group  level      
0     0   group0 High      3
                 Low       2
          group1 0High     5
                 0Low      4

如果拆分并非始终位于第6位怎么办?

This SO answer将向您展示如何更智能地进行拆分。