如何使用正则表达式对列标题进行分组?

时间:2018-01-17 11:19:41

标签: python regex pandas group-by

我有一个像这样的数据框

   S1,0  S1,0.1  S1,0.2  S1,1  S1,1.1  S1,1.2  S2,0  S2,0.1  S2,1  S2,1.1
0     4       0       3     3       3       1     3       2     4       0
1     0       4       2     1       0       1     1       0     1       4
2     3       0       3     0       2       3     0       1     3       3

现在我想要groupby列标题,其中S1,0应该在一个组中,S1,1在另一个组中,S2用于mean并应用某些操作那些团体。

我的预期结果看起来像这样(如果我计算m,称为standard deviations称为 S1,0 S1,1 S2,0 S2,1 m 0 2.333333 2.333333 2.500000 2.000000 1 2.000000 0.666667 0.500000 2.500000 2 2.000000 1.666667 0.500000 3.000000 s 0 2.081666 1.154701 0.707107 2.828427 1 2.000000 0.577350 0.707107 2.121320 2 1.732051 1.527525 0.707107 0.000000 ,则<: / p>

import pandas as pd
import numpy as np

np.random.seed(0)

data = np.random.randint(0, 5, 30).reshape(3, 10)

df = pd.DataFrame(data, columns=['S1,0', 'S1,0.1', 'S1,0.2', 'S1,1', 'S1,1.1', 'S1,1.2',
                                 'S2,0', 'S2,0.1', 'S2,1', 'S2,1.1'])

df = df.T

gdf = df.groupby(lambda x: x.split('.', 1)[0])[df.columns].agg({'m': np.mean, 's': np.std}).T.sort_index()

我可以得到这个输出:

split

我的问题是,是否有一种方法可以避免对列名称进行import re reg = re.compile('^S\d,\d') gdf2 = df.groupby(reg)[df.columns].agg({'m': np.mean, 's': np.std}).T.sort_index() 操作,但是可以通过实际的正则表达式进行操作?所以有些事情

google_maps_api.xml

这不起作用,但可能有任何可比性吗?

1 个答案:

答案 0 :(得分:1)

您可以extract使用regex

df = df.T

pat = df.index.str.extract('(^S\d,\d)', expand=False)
print (pat)
Index(['S1,0', 'S1,0', 'S1,0', 'S1,1', 'S1,1', 'S1,1', 'S2,0', 'S2,0', 'S2,1',
       'S2,1'],
      dtype='object')

df = df.groupby(pat).agg(['mean','std'])
       .T
       .swaplevel(0,1)
       .sort_index()
       .rename({'mean':'m','std':'s'})
print (df)
         S1,0      S1,1      S2,0      S2,1
m 0  2.333333  2.333333  2.500000  2.000000
  1  2.000000  0.666667  0.500000  2.500000
  2  2.000000  1.666667  0.500000  3.000000
s 0  2.081666  1.154701  0.707107  2.828427
  1  2.000000  0.577350  0.707107  2.121320
  2  1.732051  1.527525  0.707107  0.000000

另一种没有转置的解决方案,但concat是必要的:

pat = df.columns.str.extract('(^S\d,\d)', expand=False)
g = df.groupby(pat, axis=1)
df = pd.concat([g.mean(), g.std()], keys=('m','s'))
print (df)
         S1,0      S1,1      S2,0      S2,1
m 0  2.333333  2.333333  2.500000  2.000000
  1  2.000000  0.666667  0.500000  2.500000
  2  2.000000  1.666667  0.500000  3.000000
s 0  2.081666  1.154701  0.707107  2.828427
  1  2.000000  0.577350  0.707107  2.121320
  2  1.732051  1.527525  0.707107  0.000000