在Pandas数据帧中总结列的行 - 明智的行

时间:2015-05-07 02:24:02

标签: python regex pandas

使用以下代码:

import pandas as pd
df = pd.DataFrame({'ProbeGenes' : ['1431492_at Lipn', '1448678_at Fam118a','1452580_a_at Mrpl21'],
                   '(5)foo.ID.LN.x1' : [20.3, 25.3,3.1],
                   '(5)foo.ID.LN.x2' : [130, 150,173],        
                   '(5)foo.ID.LN.x3' : [1.0, 2.0,12.0],         
                   '(3)bar.ID.LN.x1' : [1,2,3],
                   '(3)bar.ID.LN.x2' : [4,5,6],        
                   '(3)bar.ID.LN.x3' : [7,8,9]        
                   })


new_cols = df.pop("ProbeGenes").str.split().apply(pd.Series)
new_cols.columns = ["Probe","Gene"]
df = df.join(new_cols)
cols = df.columns.tolist()
cols = cols[-2:] + cols[:-2]
df = df[cols]
df

我可以制作以下数据框:

          Probe     Gene  (5)bar.ID.LN.x1  (5)bar.ID.LN.x2  (5)bar.ID.LN.x3  \
0    1431492_at     Lipn                1                4                7
1    1448678_at  Fam118a                2                5                8
2  1452580_a_at   Mrpl21                3                6                9

   (3)foo.ID.LN.x1  (3)foo.ID.LN.x2  (3)foo.ID.LN.x3
0             20.3              130                1
1             25.3              150                2
2              3.1              173               12

请注意,数据框包含两个块(名为foobar),每个块包含x1,x2,x3。我想要做的是总结每个块中的值,从而产生这个数据框:

          Probe     Gene  foo   bar
     1431492_at     Lipn  151.3 12
     1448678_at  Fam118a  177.3 15
   1452580_a_at   Mrpl21  188.1 18 

实际数据可以包含两个以上的块名称。每个块将包含2或3个成员(x1,x2x1,x2,x3)。

可以使用以下正则表达式/\(\d+\)(\w+)\..*/

捕获块名称

我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:2)

如果数据量很小,则选择一个

df['foo'] = df.filter(regex='foo').sum(axis=1) # It will filter all the columns which has the word 'foo' in it
df['bar'] = df.filter(regex='bar').sum(axis=1)

如果您的数据大小超过10,000行,请不要使用此功能。通常使用axis=1进行总结很慢

答案 1 :(得分:1)

这是一种开始寻找这样的"块":

的方法
In [1266]: %timeit df[bar_cols].sum(axis=1)
1000 loops, best of 3: 476 µs per loop

In [1267]: %timeit df[[i for i in df.columns if 'bar' in i]].sum(axis=1)
1000 loops, best of 3: 483 µs per loop

In [1268]: %timeit df.filter(regex='foo').sum(axis=1)
1000 loops, best of 3: 483 µs per loop

基准:

var str = "always on the go? if yes, slip-on this dress that comes with u-        neck, long sleeves and loose fit. wear with slacks and beanie to finish the ensemble.↵↵- u-neck↵- long sleeves↵- loose fit↵- knee hemline↵- plain print"

答案 2 :(得分:1)

如果您在许多列中执行此操作,我建议使用MultiIndex而不是点分隔字符串:

In [11]: new_cols = df.pop("ProbeGenes").str.split().apply(pd.Series)  # do something with this later

In [12]: df.columns = pd.MultiIndex.from_tuples(df.columns.map(lambda x: tuple(x.split("."))))

In [13]: df
Out[13]:
  (3)bar       (5)foo
      ID           ID
      LN           LN
      x1 x2 x3     x1   x2  x3
0      1  4  7   20.3  130   1
1      2  5  8   25.3  150   2
2      3  6  9    3.1  173  12

In [14]: df.loc[:, "(3)bar"].sum(axis=1)
Out[14]:
0    12
1    15
2    18
dtype: int64