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