Pandas的groupby通过“分、用、合”实现数据聚合,支持多列分组与复杂聚合,结合filter、sort_values和reset_index可高效处理结果,并可通过优化数据类型、使用Dask等提升大数据性能。

Pandas中的
groupby
groupby
groupby
首先,你需要一个DataFrame。我们创建一个简单的例子:
import pandas as pd
import numpy as np
data = {
'城市': ['北京', '上海', '北京', '广州', '上海', '北京'],
'商品': ['A', 'B', 'A', 'C', 'B', 'C'],
'销售额': [100, 150, 200, 50, 120, 80],
'利润': [20, 30, 40, 10, 25, 15]
}
df = pd.DataFrame(data)
print("原始数据:")
print(df)1. 基本分组聚合
立即学习“Python免费学习笔记(深入)”;
如果你想知道每个城市的总销售额,你可以这样做:
# 按城市分组,计算销售额总和
city_sales = df.groupby('城市')['销售额'].sum()
print("\n按城市分组的总销售额:")
print(city_sales)这里,
df.groupby('城市')['销售额'].sum()
你也可以对多个列进行聚合,或者使用不同的聚合函数:
# 按城市分组,计算销售额的平均值和利润的最大值
city_stats = df.groupby('城市').agg({
'销售额': 'mean',
'利润': 'max'
})
print("\n按城市分组的平均销售额和最大利润:")
print(city_stats)常用的聚合函数包括:
sum()
mean()
median()
min()
max()
count()
size()
std()
var()
2. 多列分组
如果你想更细致地分析,比如想知道每个城市里,每种商品的销售额总和,那就需要多列分组:
# 按城市和商品分组,计算销售额总和
city_product_sales = df.groupby(['城市', '商品'])['销售额'].sum()
print("\n按城市和商品分组的总销售额:")
print(city_product_sales)这样会生成一个MultiIndex的Series,非常适合进行多维度的分析。
在实际的数据分析场景中,我们很少只对一个列进行简单的聚合。多列分组是常态,而复杂聚合则意味着我们可能需要对不同的列应用不同的聚合逻辑,甚至自定义聚合函数。
当我们用
df.groupby(['列1', '列2'])
对于复杂聚合,
agg()
# 示例:对不同列应用不同聚合,并使用多个聚合函数
complex_agg = df.groupby('城市').agg(
总销售额=('销售额', 'sum'), # 命名聚合,结果列名为“总销售额”
平均利润=('利润', 'mean'), # 结果列名为“平均利润”
商品种类=('商品', lambda x: x.nunique()) # 使用lambda表达式自定义聚合:计算商品种类数
)
print("\n复杂聚合操作:")
print(complex_agg)这里我用了Python的
lambda
lambda x: x.nunique()
groupby
有时,你可能需要对整个组应用一个更复杂的逻辑,而不仅仅是简单的聚合函数。这时,
apply()
apply()
# 示例:使用apply()查找每个城市销售额最高的商品
def top_product(group):
return group.loc[group['销售额'].idxmax()]
top_selling_per_city = df.groupby('城市').apply(top_product)
print("\n每个城市销售额最高的商品信息:")
print(top_selling_per_city)apply()
agg()
agg()
agg()
agg()
apply()
当我们完成分组聚合后,得到的结果往往需要进一步的整理和分析。筛选、排序和重置索引是处理
groupby
1. 筛选分组后的数据 (filter()
有时候,我们只对满足特定条件的分组结果感兴趣。比如,我们只想看到总销售额超过某个阈值的城市。这时候,
filter()
# 筛选出总销售额大于250的城市
filtered_cities = df.groupby('城市').filter(lambda x: x['销售额'].sum() > 250)
print("\n筛选出总销售额大于250的原始数据行:")
print(filtered_cities)需要注意的是,
filter()
# 先聚合,再筛选聚合结果
agg_result = df.groupby('城市')['销售额'].sum()
high_sales_cities_agg = agg_result[agg_result > 250]
print("\n筛选出总销售额大于250的城市及其总销售额(聚合结果):")
print(high_sales_cities_agg)2. 排序分组结果 (sort_values()
聚合后的数据通常是按分组键的顺序排列的,但我们可能需要根据聚合值进行排序,以便快速识别最大值或最小值。
# 按城市分组并计算总销售额,然后按销售额降序排列
sorted_city_sales = df.groupby('城市')['销售额'].sum().sort_values(ascending=False)
print("\n按总销售额降序排列的城市:")
print(sorted_city_sales)如果你的聚合结果是一个DataFrame(比如你使用了多个聚合函数),你可以指定按哪个列进行排序:
# 按城市分组,计算销售额和利润的平均值,然后按平均销售额降序排列
avg_stats = df.groupby('城市').agg({'销售额': 'mean', '利润': 'mean'})
sorted_avg_stats = avg_stats.sort_values(by='销售额', ascending=False)
print("\n按平均销售额降序排列的城市统计:")
print(sorted_avg_stats)3. 重置索引 (reset_index()
groupby
reset_index()
# 按城市和商品分组计算总销售额,并将分组键转为普通列
reset_index_example = df.groupby(['城市', '商品'])['销售额'].sum().reset_index()
print("\n重置索引后的分组聚合结果:")
print(reset_index_example)你也可以在
groupby
as_index=False
# 在groupby时就避免生成索引
no_index_groupby = df.groupby(['城市', '商品'], as_index=False)['销售额'].sum()
print("\ngroupby时设置as_index=False的结果:")
print(no_index_groupby)在我看来,
reset_index()
虽然
groupby
1. 内存消耗
groupby
apply()
优化策略:
选择合适的聚合方法: 优先使用内置的聚合函数(如
sum
mean
count
agg()
apply()
agg()
提前过滤和选择列: 在进行
groupby
使用category
category
df['城市'] = df['城市'].astype('category')
df['商品'] = df['商品'].astype('category')
# 再次进行groupby操作,可能会更快分块处理(Chunking): 对于超大型数据集,如果一次性加载会爆内存,可以考虑将数据分块加载,对每个块进行
groupby
2. apply()
前面提过,
apply()
agg()
优化策略:
尽量用agg()
transform()
apply()
agg()
transform()
# 示例:使用transform()计算每个城市的销售额占城市总销售额的比例
df['城市销售额占比'] = df.groupby('城市')['销售额'].transform(lambda x: x / x.sum())
print("\n使用transform()计算城市销售额占比:")
print(df)transform
apply
3. 数据类型不一致
在某些情况下,如果分组键的数据类型不一致(比如混合了字符串和数字),Pandas可能无法有效地优化操作,导致性能下降。确保分组键的数据类型统一且合适,能避免一些不必要的性能开销。
4. 外部库的利用
对于真正的大数据量(GB级别甚至TB级别),Pandas可能就力不从心了。这时,可以考虑使用专门为大数据设计的库:
dask.dataframe
groupby
在我实际工作中,面对大型数据集,我往往会先尝试优化Pandas本身的用法(如
category
transform
以上就是python中怎么用pandas进行分组聚合(groupby)?的详细内容,更多请关注php中文网其它相关文章!
python怎么学习?python怎么入门?python在哪学?python怎么学才快?不用担心,这里为大家提供了python速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号