Pandas分组与聚合

本文通过实例详细介绍了Pandas库中的数据分组与聚合操作,包括使用groupby方法进行分组、对不同列进行多种计算方法、窗口函数的应用等,帮助读者深入理解数据处理过程。

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

import pandas as pd
# 准备数据集
df = pd.read_excel('https://www.gairuo.com/file/data/dataset/team.xlsx')
df.head()
nameteamQ1Q2Q3Q4
0LiverE89212464
1ArryC36373757
2AckA57601884
3EorgeC93967178
4OahD65496186

分组对象具体是什么

# 创建分组对象
grouped = df.groupby('team')

# 可将grouped看成一个DataFrame,指定‘team’为分组索引,可进行迭代
for i in grouped:
    print(i)
    break # 只输出一层
('A',        name team  Q1  Q2  Q3  Q4
2       Ack    A  57  60  18  84
7      Lfie    A   9  10  99  37
9     Oscar    A  77   9  26  67
16   Joshua    A  63   4  80  30
17    Henry    A  91  15  75  17
20    Lucas    A  60  41  77  62
22   Arthur    A  44  53  42  40
34  Reggie1    A  30  12  23   9
40     Toby    A  52  27  17  68
42    Dylan    A  86  87  65  20
51    Hugo0    A  28  25  14  71
67    Caleb    A  64  34  46  88
70   Nathan    A  87  77  62  13
71    Blake    A  78  23  93   9
75  Stanley    A  69  71  39  97
79    Tyler    A  75  16  44  63
88    Aaron    A  96  75  55   8)
# 获取A组,是一个DataFrame
grouped.get_group('A')
nameteamQ1Q2Q3Q4
2AckA57601884
7LfieA9109937
9OscarA7792667
16JoshuaA6348030
17HenryA91157517
20LucasA60417762
22ArthurA44534240
34Reggie1A3012239
40TobyA52271768
42DylanA86876520
51Hugo0A28251471
67CalebA64344688
70NathanA87776213
71BlakeA7823939
75StanleyA69713997
79TylerA75164463
88AaronA9675558
# 将grouped看成一个DataFrame,取Q1列进行求和(分组求和)
print(grouped['Q1'].sum())  # 取出来是一个Series
grouped[['Q1']].sum() # 取出来是一个DataFrame
team
A    1066
B     975
C    1056
D     860
E     963
Name: Q1, dtype: int64
Q1
team
A1066
B975
C1056
D860
E963
# 只有数值字段参与求和运算
df.groupby('team').sum() 
Q1Q2Q3Q4
team
A1066639875783
B975121812021136
C1056119410681127
D860119112411199
E96310138811033

取消分组索引

# 默认以分组标签作为索引,也可取消索引
df.groupby('team', as_index=False).sum() 
teamQ1Q2Q3Q4
0A1066639875783
1B975121812021136
2C1056119410681127
3D860119112411199
4E96310138811033
df.groupby('team', as_index=False).team.count()
team
017
122
222
319
420

对不同列使用不同的计算方法

df.groupby('team', as_index=False).agg({
    'Q1':sum,
    'Q2':'count',
    'Q3':'mean',
    'Q4':max
})
teamQ1Q2Q3Q4
0A10661751.47058897
1B9752254.63636499
2C10562248.54545598
3D8601965.31578999
4E9632044.05000098
# 对同一列使用不同的计算方法
df.groupby('team').agg({'Q1':[sum,'count','std',max]})
Q1
sumcountstdmax
team
A10661724.15513696
B9752232.60789697
C10562231.00076898
D8601925.88616680
E9632033.24276797
# agg方法无法实现同一列的不同计算方法
df.groupby('team', as_index=False).agg({
    'Q1':sum,
    'Q1':'count',
    'Q1':'std',
    'Q1':max
})
teamQ1
0A96
1B97
2C98
3D80
4E97
# 分组对象使用apply()调用一个函数(此处调用lambda函数,并传入一个Series映射),传入apply()的是DataFrame
df.groupby('team', as_index=False).apply(lambda x: pd.Series({
    'Q1_sum': x['Q1'].sum(),
    'Q1_count': x['Q1'].count(),
    'Q1_std': x['Q1'].std(),
    'Q1_max': x['Q1'].max()
})) 
teamQ1_sumQ1_countQ1_stdQ1_max
0A1066.017.024.15513696.0
1B975.022.032.60789697.0
2C1056.022.031.00076898.0
3D860.019.025.88616680.0
4E963.020.033.24276797.0

以表达式、函数进行分组

# 索引值是否为偶数,分成两组
df.groupby(lambda x: x%2==0).sum() # 以默认的索引进行分组
df.groupby(df.index%2==0).sum() # 也可指定分组索引
Q1Q2Q3Q4
False2322244928232699
True2598280624442579
# 列名包含Q的分为一组
df.groupby(lambda x: 'Q' in x, axis=1).sum() #字符串求和等于拼接
FalseTrue
0LiverE198
1ArryC167
2AckA219
3EorgeC338
4OahD261
.........
95GabrielC268
96Austin7C125
97Lincoln4C212
98EliE234
99BenE179

100 rows × 2 columns

# 按姓名首字母为元音、辅音分组
def get_letter_type(letter):
    if letter[0].lower() in 'aeiou':
        return '元音'
    else:
        return '辅音'
    
# 使用上述函数进行分组
df.set_index('name').groupby(get_letter_type).sum()
Q1Q2Q3Q4
元音1462144014101574
辅音3458381538573704
# 指定多个分组索引
df.groupby(['team', df.name.apply(get_letter_type)]).sum()
Q1Q2Q3Q4
teamname
A元音274197141199
辅音792442734584
B元音309291269218
辅音666927933918
C元音473488453464
辅音583706615663
D元音273333409486
辅音587858832713
E元音133131138207
辅音830882743826

将分组中的一列输出为列表

# 创建示例数据
tmp = pd.DataFrame({'team':['A','A','A','B','B','B'],'name':['Eric','Eric','Tony','Tony','Tom','Tom',]})
tmp
teamname
0AEric
1AEric
2ATony
3BTony
4BTom
5BTom
tmp.groupby('team').apply(lambda x: x['name'].to_list())
team
A    [Eric, Eric, Tony]
B      [Tony, Tom, Tom]
dtype: object
# 去重后输出列表:unique
pd.DataFrame(tmp.groupby('team')['name'].unique()).rename(columns={'name':'agg_name'})
agg_name
team
A[Eric, Tony]
B[Tony, Tom]
# 去重后输出列表长度:nunique
pd.DataFrame(tmp.groupby('team')['name'].nunique()).rename(columns={'name':'num'})
num
team
A2
B2
# 使用apply() 合并输出上述2个结果
tmp.groupby('team', as_index=False).apply(lambda x: pd.Series({
    'agg_name': x['name'].unique(),
    'num': x['name'].nunique()
}))
teamagg_namenum
0A[Eric, Tony]2
1B[Tony, Tom]2

窗口函数

df['Q1_mean'] = df.groupby('team')['Q1'].transform('mean')
df.sort_values(by='team', ascending=False)
nameteamQ1Q2Q3Q4Q1_meanQ1_size
0LiverE8921246448.15000020
19MaxE977541348.15000020
26TeddyE7191214848.15000020
29RileyE3526598348.15000020
31JosephE6787879348.15000020
...........................
34Reggie1A301223962.70588217
70NathanA8777621362.70588217
79TylerA7516446362.70588217
71BlakeA782393962.70588217
51Hugo0A2825147162.70588217

100 rows × 8 columns

df['Q1_size'] = df.groupby('team')['Q1'].transform('count')
df.sort_values(by='team', ascending=False)
nameteamQ1Q2Q3Q4Q1_meanQ1_size
0LiverE8921246448.15000020
19MaxE977541348.15000020
26TeddyE7191214848.15000020
29RileyE3526598348.15000020
31JosephE6787879348.15000020
...........................
34Reggie1A301223962.70588217
70NathanA8777621362.70588217
79TylerA7516446362.70588217
71BlakeA782393962.70588217
51Hugo0A2825147162.70588217

100 rows × 8 columns


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值