5

我有一个 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

参考

  • 一个类似的问题推荐了一个专家组。我一直无法找出正确的索引来完成这项工作。
4

1 回答 1

7

使用groupby 的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

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

然后,您可以将索引设置为 event 和 node 以获得您想要的结果:

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
于 2013-08-22T20:08:54.090 回答