下面是我想要过滤的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
答案 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