Pandas中的groupby以及agg,filter,transform对比

本文详细介绍了如何使用Pandas库进行数据分组(groupby)及后续的聚合操作,包括计数、平均值计算、筛选子集和转换数据等技巧。通过实际案例,如Titanic数据集的生存率分析,展示了groupby函数的强大功能及其参数as_index的影响。此外,还对比了agg、filter和transform函数在不同场景下的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

pd.groupby 作用

pd.groupby 能将feature按不同类型分开

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
df_train = pd.read_csv("train.csv") # titanic数据

查看统计

df_train.groupby(['Sex','Survived'])['Survived'].count()




Sex     Survived
female  0            81
        1           233
male    0           468
        1           109
Name: Survived, dtype: int64

画出性别对应的生存率

df_train[['Sex','Survived']].groupby(['Sex']).mean().plot.bar()




<matplotlib.axes._subplots.AxesSubplot at 0x1f8d3c93198>

pgn

df = pd.DataFrame(data={'books':['bk1','bk1','bk1','bk2','bk2','bk3'], 'price': [12,12,12,15,15,17]})


df
booksprice
0bk112
1bk112
2bk112
3bk215
4bk215
5bk317
df0 = df.groupby('books',as_index=True).sum()
print (df0.loc['bk1'])

price    36
Name: bk1, dtype: int64



df0.loc[0]   #报错





df1 = df.groupby('books',as_index=False).sum()
print (df1.loc[df1.books == 'bk1'])

  books  price
0   bk1     36



df1.loc['bk1']  # 报错


当as_index = True 时,df.loc[]只能用label来,比如’bk1’

当as_index =False 时,df.loc[]只能用索引来 ,比如 0,1,2

但是都能用 df.iloc[]来索引,结果一致

agg vs filter vs transform

链接里有详细的教程

简单用法

df.groupby('day')['total_bill'].mean()
df.groupby('day').filter(lambda x : x['total_bill'].mean() > 20)
df.groupby('day')['total_bill'].transform(lambda x : x/x.mean())

适用条件

  • if we want to get a single value for each group -> use aggregate()

  • if we want to get a subset of the input rows -> use filter()

  • if we want to get a new value for each input row -> use transform()

<think>嗯,用户想了解Pandasgroupby的高级用法,特别是多级分组、聚合和自定义函数。首先,我需要回忆一下Pandas的相关文档和常用方法。记得groupby的基本用法是对数据进行分组,然后应用聚合函数,比如sum、mean等。但高级用法可能包括多级分组,也就是按照多个列进行分组,形成层次化的索引。 接下来是聚合部分,用户提到了自定义函数。我记得agg()方法可以同时应用多个聚合函数,或者对不同的列应用不同的函数。例如,可以对一列求和,另一列求平均值。另外,用户可能还需要知道如何自定义聚合函数,比如计算某个统计量或者处理异常值后的聚合。 然后是多级分组,可能需要使用groupby时传入多个列名的列表,这样会生成多级索引。之后可能需要用到unstack或者reset_index来调整结果的格式。此外,多级分组后的聚合可能需要指定不同层级的聚合方式,或者使用transform、apply等方法进行更灵活的操作。 自定义函数方面,用户可能希望例子具体一些,比如定义一个返回均值和标准差的函数,或者处理字符串的函数。需要注意的是,自定义函数需要能够处理Series输入,并返回一个标量值或Series。如果是返回多个值,可能需要使用agg配合特定的参数,或者返回Series以生成多列。 另外,用户提到的示例可能需要展示如何将多级分组和聚合结合起来,比如按照地区和产品类别分组,然后对销售额和利润进行不同的聚合操作。同时,可能需要展示如何链式调用多个方法,比如在分组聚合后重命名列名,或者进行数据透视。 还要注意引用站内的资料,比如引用[1]提到agg()可以同时应用多个聚合函数,引用[3]介绍了自定义聚合函数的方法。需要将这些引用自然地融入到回答中,比如在讲解agg()时提到引用[1],在自定义函数部分提到引用[3]。 此外,用户的问题可能隐含了对性能优化的需求,比如在大数据集下如何高效地进行分组聚合,或者如何处理分组后的复杂操作。不过用户的问题主要是用法示例,所以可能不需要深入讨论性能,但可以简要提及。 可能还需要考虑多级分组后的结果如何处理,比如使用unstack将行转列,或者使用reset_index将多级索引转换为普通列。同时,transform和apply方法的区别,transform返回与原始数据相同长度的结果,而apply更灵活,但可能效率较低。 总结一下,回答的结构应该是先介绍多级分组,然后讲解聚合的高级用法,包括自定义函数,最后给出综合示例。需要确保每个部分都有代码示例,并引用相关的资料。可能还需要提醒用户注意groupby后的对象类型,以及如何处理分组后的数据。</think>### Pandas groupby 高级用法详解 #### 1. **多级分组** 通过多个维度对数据进行分组,形成层次化索引结构。例如,按`地区`和`产品类别`分组: ```python import pandas as pd # 示例数据 data = { '地区': ['北京', '上海', '北京', '上海', '北京'], '产品类别': ['电子', '食品', '电子', '食品', '食品'], '销售额': [200, 150, 300, 80, 120], '利润': [40, 30, 60, 15, 25] } df = pd.DataFrame(data) # 多级分组 grouped = df.groupby(['地区', '产品类别']) print(grouped.groups) # 查看分组结构 ``` #### 2. **高级聚合操作** 使用`agg()`方法实现多列不同聚合函数,或对单列应用多个函数: ```python # 对不同列应用不同聚合函数 result = grouped.agg({ '销售额': ['sum', 'mean'], '利润': ['max', lambda x: x.max() - x.min()] # 自定义差值计算 }).reset_index() # 输出结果 print(result) ``` **输出示例**: ``` 地区 产品类别 销售额 利润 sum mean max <lambda_0> 0 北京 电子 500 250.0 60 20 1 北京 食品 120 120.0 25 10 2 上海 食品 230 115.0 30 15 ``` #### 3. **自定义聚合函数** 结合`agg()`定义复杂逻辑,例如计算**均值+标准差**或**分位数范围**: ```python # 自定义函数返回多指标(生成多列) def custom_agg(series): return pd.Series({ 'mean_std': f"{series.mean():.1f}±{series.std():.1f}", 'q75-q25': series.quantile(0.75) - series.quantile(0.25) }) # 应用自定义函数 result_custom = df.groupby('地区')['销售额'].agg(custom_agg).reset_index() print(result_custom) ``` **输出示例**: ``` 地区 mean_std q75-q25 0 北京 206.7±76.4 130.0 1 上海 115.0±49.5 70.0 ``` #### 4. **分组后处理** 使用`transform`和`apply`实现更灵活操作: ```python # 示例:计算每个分组的标准化值(Z-Score) df['标准化销售额'] = df.groupby('地区')['销售额'].transform( lambda x: (x - x.mean()) / x.std() ) # 示例:筛选每组销售额前N的记录 def filter_topn(group, n=1): return group.nlargest(n, '销售额') top_sales = df.groupby('地区', group_keys=False).apply(filter_topn, n=1) print(top_sales) ``` #### 5. **多级索引操作** 处理分组后的层次化索引: ```python # 将多级索引转换为列 result_unstacked = result.unstack(level='产品类别') # 使用swaplevel调整索引层级 result_swapped = result.swaplevel(i=0, j=1, axis=1) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值