如果一行符合条件,则从pandas数据框中删除级别及其所有行

时间:2018-04-03 20:49:50

标签: python pandas

下面是我想要过滤的pandas数据框。我希望在该年度至少有一行(即visit)的临界值<1时删除年份及其所有行。 37.我能够删除2014年临时值为36的具体行;但是,我不知道如何让整年都消失。

index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]], names=['yr', 
                                                                  'visit'])
columns = pd.MultiIndex.from_product(['hr', 'temp'], names=['metric'])
data = pd.DataFrame([[96, 38], [98, 38], [85, 36], [84, 43]], index=index, 
                    columns=columns)
data

        metric  hr      temp    
yr      visit                       
2013    1       96      38  
        2       98      38  
2014    1       85      36  
        2       84      43  

期望的输出:

        metric  hr      temp    
yr      visit                       
2013    1       96      38  
        2       98      38  

2 个答案:

答案 0 :(得分:3)

您可以使用groupby/filter根据条件删除群组:

import numpy as np
import pandas as pd

index = pd.MultiIndex.from_product([[2013, 2014], [1, 2]], names=['yr', 'visit'])
columns = pd.MultiIndex.from_product([['hr', 'temp']], names=['metric'])
data = pd.DataFrame([[96, 38], [98, 38], [85, 36], [84, 43]], index=index, columns=columns)

print(data.groupby(level='yr').filter(lambda x: (x['temp']>=37).all()))

产量

metric      hr temp
yr   visit         
2013 1      96   38
     2      98   38

由于您要删除的行按yr分组,而yr是索引的级别,因此请使用groupby(level='yr')。对于每个组,调用lambda函数并将x设置为子DataFrame组。小组保持时间 (x['temp']>=37).all())True

请注意Wen's suggestion

data.loc[(data['temp']>=37).groupby(level='yr').transform('all')]

更快,特别是对于大型DataFrame,因为data['temp']>=37以矢量化方式计算整个列的标准,而在上面的解决方案中,(x['temp']>=37).all()计算标准每个子DataFrame分别以零碎的方式。通常,矢量化解决方案在应用于大型阵列或NDFrame时更快,而不是在较小的块上循环。

以下示例显示了1000行DataFrame的速度差异:

In [70]: df = pd.DataFrame(np.random.randint(100, size=(1000, 4)), columns=list('ABCD')).set_index(['A','B'])

In [71]: %timeit df.groupby(level='A').filter(lambda x: (x['C']>=5).all())
10 loops, best of 3: 46.3 ms per loop

In [72]: %timeit df.loc[(df['C']>=37).groupby(level='A').transform('all')]
100 loops, best of 3: 18.9 ms per loop

答案 1 :(得分:0)

使用.loc

import pandas as pd

index = pd.MultiIndex.from_product(
  [[2013, 2014], [1, 2]], names=['yr', 'visit'])

columns = pd.MultiIndex.from_product([['hr', 'temp']], names=['metric'])

data = pd.DataFrame([[96, 38], [98, 38], [85, 36], [84, 43]], 
                    index=index, columns=columns)

data.loc[[2013]]

给出:

metric      hr  temp
yr   visit
2013 1      96    38
     2      98    38