Python案例如何用Pandas做数据分组合并

wen python案例 1

Python案例详解如何用Pandas做数据分组合并

📖 目录导读

  1. 数据分组合并的核心概念
  2. 准备工作:环境搭建与数据构造
  3. 单列分组+聚合函数合并
  4. 多列分组+自定义合并逻辑
  5. 分组后横向合并(拼接列)
  6. 分组内纵向合并(拼接行)
  7. 常见问题与优化技巧
  8. Q&A 实战问答

数据分组合并的核心概念

在数据分析中,我们经常需要将数据按某个类别分组,再对组内数据进行汇总或合并,Pandas提供了groupby()merge()/concat()的灵活组合,实现“先拆分,再合并”的场景。

Python案例如何用Pandas做数据分组合并

为什么需要分组合并?

  • 按地区汇总销售数据后,再与地区信息表合并
  • 按用户分组后,将同一用户的多条行为记录合并为一条序列
  • 分组计算统计指标后,再横向附加到原始数据

准备工作:环境搭建与数据构造

import pandas as pd
import numpy as np
# 创建示例数据:销售订单表
orders = pd.DataFrame({
    'order_id': ['A01','A02','A03','A04','A05'],
    'customer_id': ['C1','C1','C2','C3','C2'],
    'product': ['手机','耳机','充电器','手机','耳机'],
    'amount': [5000, 200, 150, 4800, 250],
    'date': ['2024-01-01','2024-01-02','2024-01-01','2024-01-03','2024-01-02']
})
# 客户信息表
customers = pd.DataFrame({
    'customer_id': ['C1','C2','C3'],
    'city': ['北京','上海','广州'],
    'level': ['VIP','普通','普通']
})
print(orders)
print(customers)

案例一:单列分组+聚合函数合并

需求:按customer_id分组,计算每个客户的消费总额,再合并客户城市信息。

# 第一步:分组聚合
customer_amount = orders.groupby('customer_id')['amount'].sum().reset_index()
customer_amount.columns = ['customer_id', 'total_amount']
# 第二步:合并客户信息
result = pd.merge(customer_amount, customers, on='customer_id', how='left')
print(result)

输出: | customer_id | total_amount | city | level | |-------------|--------------|------|-------| | C1 | 5200 | 北京 | VIP | | C2 | 400 | 上海 | 普通 | | C3 | 4800 | 广州 | 普通 |

💡 技巧reset_index()将分组键变回列,方便后续合并。


案例二:多列分组+自定义合并逻辑

需求:按customer_iddate分组,将同一客户同一天的多个商品合并为一条字符串。

# 自定义合并函数:将产品名用逗号连接
def merge_products(series):
    return '、'.join(series)
grouped = orders.groupby(['customer_id', 'date']).agg({
    'product': merge_products,
    'amount': 'sum'
}).reset_index()
print(grouped)

输出: | customer_id | date | product | amount | |-------------|------------|--------------|--------| | C1 | 2024-01-01 | 手机 | 5000 | | C1 | 2024-01-02 | 耳机 | 200 | | C2 | 2024-01-01 | 充电器 | 150 | | C2 | 2024-01-02 | 耳机 | 250 | | C3 | 2024-01-03 | 手机 | 4800 |


案例三:分组后横向合并(拼接列)

需求:将分组统计的指标(如均值、总和)作为新列拼接到原始数据中。

# 计算每个客户的消费均值
mean_amount = orders.groupby('customer_id')['amount'].transform('mean')
# 直接作为新列加入
orders['customer_avg'] = mean_amount
print(orders[['order_id','customer_id','amount','customer_avg']])

🔑 注意transform()保留原始行数,是横向合并的快捷方法。


案例四:分组内纵向合并(拼接行)

需求:按产品类别分组,将每个组内的所有订单记录合并为一个DataFrame子集,再导出为独立文件。

for product_name, group_df in orders.groupby('product'):
    # 对每个组内数据可以进一步处理或保存
    print(f"产品:{product_name},订单数:{len(group_df)}")
    # group_df.to_csv(f'{product_name}_orders.csv', index=False)

常见问题与优化技巧

问题 解决
分组后索引混乱 使用reset_index(drop=True)重置
合并后列名冲突 添加suffixes=('_left','_right')参数
大数据量分组慢 使用categorical dtype对分组列优化
需要保留分组键 确保groupby(..., as_index=False)

代码优化示例

# 优化分组列数据类型
orders['customer_id'] = orders['customer_id'].astype('category')
# 分组时避免生成分层索引
result = orders.groupby('customer_id', as_index=False)['amount'].sum()

Q&A 实战问答

Q1: groupby之后如何同时合并多个统计指标?
A: 使用agg()字典参数:

orders.groupby('customer_id').agg({
    'amount': ['sum','mean','count'],
    'product': lambda x: list(x)
})

Q2: 分组合并后数据行数为什么变少?
A: groupby().agg()默认会压缩数据,每一组只保留一行,若需保持原行数,使用transform()

Q3: 如何按条件分组后再合并外部表?
A: 先用布尔索引筛选数据,再分组合并:

filtered = orders[orders['amount'] > 200]
grouped = filtered.groupby('customer_id')['amount'].sum().reset_index()
final = pd.merge(grouped, customers, on='customer_id')

Q4: 三个DataFrame如何实现分组嵌套合并?
A: 分步处理,先合并前两个,再合并第三个:

step1 = orders.groupby('customer_id').agg(...).reset_index()
step2 = pd.merge(step1, customers, on='customer_id')
final = pd.merge(step2, products_info, left_on='product', right_on='product_id')

通过以上四个案例,您已掌握Pandas数据分组合并的核心技巧,从最简单的聚合统计到自定义合并逻辑,再到性能优化,这些方法足够应对90%以上的数据分析需求,建议在实际项目中先画出数据关系图,再选择最合适的合并方式。

抱歉,评论功能暂时关闭!