使用单索引布尔索引器获取Pandas DataFrame多级索引的子集

3
如果我有这个数据框:
import pandas as pd
tuples_index = [(1,1990), (2,1999), (2,2002), (3,1992), (3,1994), (3,1996)]
index = pd.MultiIndex.from_tuples(tuples_index, names=['id', 'FirstYear'])
df = pd.DataFrame([2007, 2006, 2006, 2000, 2000, 2000], index=index, columns=['LastYear'] )

df
Out[2]: 
              LastYear
id FirstYear          
1  1990           2007
2  1999           2006
   2002           2006
3  1992           2000
   1994           2000
   1996           2000

我希望能够获取数据框的子集,其中基于id的分组长度大于1,我可以这样做,但速度较慢:

%timeit df.groupby(level=0).filter(lambda x: len(x) > 1)
1000 loops, best of 3: 1.36 ms per loop

我的数据框有数千万行和大量分组(大多数分组长度为1),因此时间会累积。 我可以通过以下方式更快地获得布尔索引:

%timeit df.groupby(level=0).size() > 1
1000 loops, best of 3: 364 µs per loop

但是布尔索引器只有 id 作为它的索引:

id
1    False
2     True
3     True

我猜可能我提供的背景信息过多了,但如果我想使用布尔索引器和单个索引从具有MultiIndex的数据帧中获取子集,该怎么做呢?期望的输出为:

              LastYear
id FirstYear          
2  1999           2006
   2002           2006
3  1992           2000
   1994           2000
   1996           2000

1
任何需要从原始DataFrame复制数据到新DataFrame的操作,如果DataFrame很大,往往会变慢。df.groupby(level = 0).filter(lambda x:len(x)> 1)很慢,因为它返回一个新的DataFrame,其中包含从原始DataFrame的任意位置复制的数据。df.groupby(level=0).size() > 1相对较快,因为它生成的是一个较小的DataFrame -- 需要复制的数据较少。使用布尔索引器生成过滤后的DataFrame将无法节省时间,因为该步骤将需要复制。 - unutbu
我没有意识到它是这样工作的,谢谢!考虑到没有真正的解决方案,关闭问题的正确方式是什么? - jesseWUT
我没有将上面的陈述作为答案发布,因为我无法证明它是正确的。也许最好保持问题的开放性,以防我错了。上面的评论要么经得起时间的考验,要么挑战某人展示有更快的方法。 - unutbu
1个回答

0
使用groupbytransform构建掩码。
df[df.groupby(level=0).transform(np.size).gt(1).values]

enter image description here


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接