在DataFrame上选择多个横截面的正确方法

时间:2013-08-22 19:48:29

标签: pandas

我有一个MultiIndex DataFrame,我在其上选择有趣的横截面。代码有效,但在大型数据集上运行缓慢,这让我觉得我做错了。基本上我已经将多个横截面连接成一个新的DataFrame,我正在寻找一种更好的方法。

数据集

import pandas as pd
import numpy as np
import itertools

# setup dataset
event = ['event0', 'event1', 'event2']
node = ['n0', 'n1', 'n2', 'n3']
config = ['a', 'b']
data = []
for x in itertools.product(*[event, node, config]):
    data.append([x[0], x[1], x[2], np.random.randn()])
df = pd.DataFrame(data, columns=['event', 'node', 'config', 'value'])
dfi = df.set_index(['event', 'node'])
print dfi.head(n=12)

看起来像:

            config     value
event  node
event0 n0        a  1.256259
       n0        b  0.612465
       n1        a  1.593518
       n1        b -0.747131
       n2        a  0.719973
       n2        b  1.063480
       n3        a -0.943120
       n3        b  2.021804
event1 n0        a -1.427104
       n0        b -0.440886
       n1        a  0.168212
       n1        b -1.084987

一些分析

我做了一些分析,它给出了我关心的索引列表:

# Find interesting (event,node) 
g = df.groupby(['event', 'node'])['value']
gmin = g.min()
idxs = gmin[(gmin<-1.2)].index
print idxs
#idxs = [(u'event1', u'n0'), (u'event1', u'n2'), (u'event2', u'n0')]

笨拙的横截面

现在我只关心有趣的事件,节点组合。这是在实际数据集上很慢的部分。每个.xs可能需要100毫秒,但它们相加:  

df2 = pd.concat([dfi.xs(idx) for idx in idxs]) 
print df2

其中给出了有趣(事件,节点)横截面的每个配置的值:

            config     value
event  node
event1 n0        a -1.427104
       n0        b -0.440886
       n2        a  0.273871
       n2        b -1.224801
event2 n0        a -1.297496
       n0        b -1.087568

参考

  • 类似question推荐小组。我无法找到合适的索引来完成这项工作。

1 个答案:

答案 0 :(得分:7)

使用groupby's filter方法(0.12中的新内容)会更好,这是为了这个目的而设计的:

In [11]: g = df.groupby(['event', 'node'])

In [12]: g.filter(lambda x: x['value'].min() < -1.2)
Out[12]: 
     event node config     value
0   event0   n0      a -1.566442
1   event0   n0      b -1.652915
14  event1   n3      a  1.685070
15  event1   n3      b -3.205499
20  event2   n2      a -3.007079
21  event2   n2      b  0.159409

(我的数字不同,因为它们是随机生成的!)

然后您可以set the index到事件和节点以获得所需的结果:

In [13]: g.filter(lambda x: x['value'].min() < - 1.2).set_index(['event', 'node'])
Out[13]: 
            config     value
event  node                 
event0 n0        a -1.566442
       n0        b -1.652915
event1 n3        a  1.685070
       n3        b -3.205499
event2 n2        a -3.007079
       n2        b  0.159409