Pandas - 根据索引内所有值的条件过滤多级索引

5

我正在尝试过滤一个类似于以下多级索引的数据框。

import numpy as np
import pandas as pd

data = pd.DataFrame(np.random.rand(8),
             index=[list('AABBCCDD'),
                    ['M', 'F']*4])
data['Count'] = [1,2,15,17,8,12,11,20]

我想选择所有在给定外部索引内,'M' 和 'F' 的 'Count' 均大于10的行。对于示例数据框,应该选择所有'B'和'D'行,但不选择其他任何行。我只能想到通过循环遍历外部索引来实现这一点,但由于 pandas 中的循环几乎从来不是最佳解决方案,因此我认为可能有更好的解决方案。

3个回答

6

使用groupby对索引进行分组,然后使用filter+all来获取计数超过阈值的所有值。

data.groupby(level=0).filter(lambda x : x['Count'].gt(10).all())
Out[495]: 
            0  Count
B M  0.232856     15
  F  0.536026     17
D M  0.375064     11
  F  0.795447     20

灵感来源于 Jpp 使用 isin

s=data.Count.min(level=0).gt(10)
data.loc[data.index.get_level_values(0).isin(s[s].index)]

3

选项1

使用级别掩码进行堆叠和取消堆叠

data.unstack()[data.Count.gt(10).all(level=0)].stack()

            0  Count
B F  0.778883     17
  M  0.548054     15
D F  0.035073     20
  M  0.544838     11

选项2

使用pandas.Series.allpd.DataFrame.reindexlevel参数。
这避免了堆叠/解堆叠的操作。

mask = data.Count.gt(10).all(level=0)
data.reindex(mask.index[mask], level=0)

            0  Count
B M  0.548054     15
  F  0.778883     17
D M  0.544838     11
  F  0.035073     20

2
您可以使用groupby.transform来实现矢量化的解决方案:
res = data[data.groupby(data.index.get_level_values(0))['Count'].transform('min') > 10]

print(res)

#             0  Count
# B M  0.143501     15
#   F  0.964689     17
# D M  0.092362     11
#   F  0.981470     20

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