Pandas - 在索引中的所有值上按条件过滤多索引

时间:2018-04-16 16:44:02

标签: python pandas dataframe

我正在尝试使用类似于以下内容的多索引过滤数据框。

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'在给定的外层索引中大于10.因此对于示例数据帧,所有'B应选择'和'D'行,但不选择其他行。我能想到的唯一方法就是循环遍历外部索引,但由于大熊猫中的循环几乎不是最好的做事方式,我认为必须有更好的解决方案。

3 个答案:

答案 0 :(得分:5)

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)]

答案 1 :(得分: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

levelpandas.Series.all使用pd.DataFrame.reindex参数。
这可以避免拆散/堆叠

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 :(得分: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