Pandas 的 filter() 方法根据指定的索引标签对数据框行或列查询子集。它支持 DataFrame、Series 和 分组对象 DataFrameGroupBy 来使用。
DataFrame
语法
DataFrame 使用时的语法为:
df.filter(
items=None,
like: 'str | None' = None,
regex: 'str | None' = None,
axis=None,
) -> 'FrameOrSeries'
参数:
- items:list-like,对应轴的标签名列表
- like:str,支持对应标签名的模糊名查询
- regex:str (正则表达式),按正则表达式查询标签名
- axis:{0 or ‘index’, 1 or ‘columns’, None}, default None,要筛选的轴,表示为索引(int)或轴名称(str)。默认情况下为列名,‘index’ 为 Series, ‘columns’ 为 DataFrame
返回:
- 与输入对象类型相同
用法
需要注意的是,此方法不会对数据帧的数据内容进行过滤,仅应用于按标签筛选。
其中的参数 items, like, 和 regex parameters 被强制执行为相互排斥,即只能有一个存在。轴默认为使用 [] 索引时使用的信息轴(info axis,按行)。
案例
# 数据集
df = pd.DataFrame(np.array(([1, 2, 3], [4, 5, 6])), index=['mouse', 'rabbit'], columns=['one', 'two', 'three']) df ''' one two three mouse 1 2 3 rabbit 4 5 6 '''
# 按名称选择列
df.filter(items=['one', 'three']) ''' one three mouse 1 3 rabbit 4 6 '''
# 按正则表达式选择列
df.filter(regex='e$', axis=1) ''' one three mouse 1 3 rabbit 4 6 '''
# 选择包含“bbi”的行
df.filter(like='bbi', axis=0) ''' one two three rabbit 4 5 6 '''
更多代码示例:
df.filter(items=['Q1', 'Q2']) # 选择两列 df.filter(regex='Q', axis=1) # 列名包含Q的 df.filter(regex='e$', axis=1) # 以 e 结尾的 df.filter(regex='1$', axis=0) # 正则, 索引名包含1的 df.filter(like='2', axis=0) # 索引中有2的 # 索引中2开头列名有Q的 df.filter(regex='^2', axis=0).filter(like='Q', axis=1)
Series
Series 应用 filter 时参数与 df.filter 一样,不过由于 Series 只有一个轴,不能将 axis = 1,只能按索引查询数据。以下为示例:
# 以下代码得到同样的结果
df.one.filter(['mouse']) df.one.filter(like='se') df.one.filter(regex='e$') ''' mouse 1 Name: one, dtype: int64 '''
DataFrameGroupBy
分组对象的使用上,它可以返回不包含筛选元素的数据框的副本。如果组中的元素不满足函数指定的布尔表达式(为 False),则会将其筛选过滤掉。filter 的函数 func 经常和匿名函数 lambda 配合使用,用来筛选 groupby 之后的数据,它类似 SQL 中 groupby 后的 having 操作。
语法
它的使用语法为:
DataFrameGroupBy.filter(func, dropna=True,
*args, **kwargs)
参数:
- func:函数,函数应用于每个分组的子帧,应该返回 True 或 False。
- dropna:删除未通过筛选器的组。默认为 True,如果为 False,则评估为 False 的组将填充 NaN
*args, **kwargs
:func 的参数
返回:
- 通过筛选操作后的 DataFrame
注:每个子帧都被赋予 “name” 属性,以防您需要知道正在处理哪个组。变异传递对象的函数可能会产生意外行为或错误,因此不支持。
使用案例
以下展示了一个分组筛选的示例:
df = pd.DataFrame({'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar'], 'B' : [1, 2, 3, 4, 5, 6], 'C' : [2.0, 5., 8., 1., 2., 9.]}) df ''' A B C 0 foo 1 2.0 1 bar 2 5.0 2 foo 3 8.0 3 bar 4 1.0 4 foo 5 2.0 5 bar 6 9.0 ''' # 分组 grouped = df.groupby('A') # 分组筛选,筛选所在组组B列平均值大于3的所有数据 grouped.filter(lambda x: x['B'].mean() > 3.) '''
A B C
1 bar 2 5.0
3 bar 4 1.0
5 bar 6 9.0
'''
结果是,筛选所在组组B列平均值大于3的所有数据。
其他代码示例:
# 值的长度都大于等于 3 的 df.groupby('team').filter(lambda x: len(x) >= 3) # Q1成绩只要有一个大于97的组 df.groupby(['team']).filter(lambda x: (x['Q1'] > 97).any()) # 所有成员平均成绩大于 60 的组 df.groupby(['team']).filter(lambda x: (x.mean() >= 60).all()) # Q1 所有成员成绩之和超过 1060 的组 df.groupby('team').filter(lambda g: g.Q1.sum() > 1060)
支持对象
总结一下,可以调用 apply()
的对象还有以下对象有:
- pandas.DataFrame.filter
- pandas.Series.filter
- pandas.core.groupby.DataFrameGroupBy.filter