如何在Pandas DataFrame中按连续Placement分组求最值?
问题描述
给定如下Pandas DataFrame:
Value Placement 0 12 high 1 15 high 2 18 high 3 14 high 4 4 low 5 5 low 6 9 high 7 11 high 8 2 low 9 1 low 10 3 low 11 2 low
需要生成目标DataFrame,规则如下:
- 每个连续的
high分组取Value列最大值 - 每个连续的
low分组取Value列最小值 - 保留原行顺序,且禁止使用低效的DataFrame迭代方式
期望输出:
Value Placement 0 18 high 1 4 low 2 11 high 3 1 low
非迭代实现方案
核心是先识别连续的Placement分组,再针对分组类型执行对应聚合操作,全程利用Pandas向量化操作,避免迭代。
实现步骤与代码
- 生成连续分组标识:通过对比当前行与上一行的
Placement值,创建分组ID,将连续相同的Placement归为同一组 - 按分组聚合:根据每组的
Placement类型,选择max或min聚合Value列
import pandas as pd # 构造原始DataFrame df = pd.DataFrame({ 'Value': [12, 15, 18, 14, 4, 5, 9, 11, 2, 1, 3, 2], 'Placement': ['high', 'high', 'high', 'high', 'low', 'low', 'high', 'high', 'low', 'low', 'low', 'low'] }) # 步骤1:创建连续分组ID df['group_id'] = (df['Placement'] != df['Placement'].shift()).cumsum() # 步骤2:定义聚合逻辑,按分组处理 def process_group(group): placement = group['Placement'].iloc[0] value = group['Value'].max() if placement == 'high' else group['Value'].min() return pd.Series({'Value': value, 'Placement': placement}) # 执行聚合并重置索引 result = df.groupby('group_id').apply(process_group).reset_index(drop=True) print(result)
更简洁的写法
可以用字典映射聚合函数,进一步简化代码:
import pandas as pd df = pd.DataFrame({ 'Value': [12, 15, 18, 14, 4, 5, 9, 11, 2, 1, 3, 2], 'Placement': ['high', 'high', 'high', 'high', 'low', 'low', 'high', 'high', 'low', 'low', 'low', 'low'] }) # 生成连续分组ID group_id = (df['Placement'] != df['Placement'].shift()).cumsum() # 定义聚合函数映射 agg_rules = {'high': 'max', 'low': 'min'} # 分组聚合:先按group_id和Placement分组,再用对应规则聚合Value result = df.groupby([group_id, 'Placement'])['Value'].agg(lambda x: agg_rules[x.name[1]]).reset_index() # 移除group_id列并重置索引 result = result.drop(columns='group_id').reset_index(drop=True) print(result)
原理说明
(df['Placement'] != df['Placement'].shift()).cumsum():当当前行的Placement与上一行不同时,生成一个新的分组ID,确保连续相同的Placement被归为一组- 分组聚合时直接利用Pandas的
groupby机制,全程是向量化操作,比逐行迭代效率高得多,尤其适合大数据量场景
内容的提问来源于stack exchange,提问作者Jordan
相关产品推荐
相关产品推荐

