如何按特定分组规则对Pandas DataFrame进行排序?
按指定分组规则排序DataFrame
需求说明
给定如下原始DataFrame:
import pandas as pd df = pd.DataFrame({ 'Name': ['Max', 'Stefan', 'John', 'Kate', 'Walter', 'Karin', 'Julia', 'Ben', 'Spencer'], 'Balance': [0.12, 0.03, 0.12, 0.12, 0.12, 0.03, 0.03, 0.06, 0.03] })
需要按每3行一组的规则排序:
- 组内第一行:取
Balance列的最大值对应行 - 组内第二行:取介于最大值和最小值之间的值对应行(允许等于最大值/最小值,或满足
max > 平均值 > min) - 组内第三行:取
Balance列的最小值对应行
同时需兼容所有值相等的场景,此时组内顺序可灵活调整。
目标输出结果:
Name Balance 0 Max 0.12 1 Ben 0.06 2 Julia 0.03 3 Kate 0.12 4 Walter 0.12 5 Karin 0.03 6 John 0.12 7 Stefan 0.03 8 Spencer 0.03
实现代码
import pandas as pd from collections import deque # 原始数据 df = pd.DataFrame({ 'Name': ['Max', 'Stefan', 'John', 'Kate', 'Walter', 'Karin', 'Julia', 'Ben', 'Spencer'], 'Balance': [0.12, 0.03, 0.12, 0.12, 0.12, 0.03, 0.03, 0.06, 0.03] }) # 提取Balance的极值 max_val = df['Balance'].max() min_val = df['Balance'].min() # 拆分三类行:最大值行、中间值行、最小值行 max_rows = df[df['Balance'] == max_val].reset_index(drop=True) mid_rows = df[(df['Balance'] > min_val) & (df['Balance'] < max_val)].reset_index(drop=True) min_rows = df[df['Balance'] == min_val].reset_index(drop=True) # 转为队列方便按顺序取数 max_q = deque(max_rows.to_dict('records')) mid_q = deque(mid_rows.to_dict('records')) min_q = deque(min_rows.to_dict('records')) result = [] num_groups = len(df) // 3 # 总组数 for _ in range(num_groups): group = [] # 组内第一行:优先取最大值行 if max_q: group.append(max_q.popleft()) elif mid_q: group.append(mid_q.popleft()) else: group.append(min_q.popleft()) # 组内第二行:优先取中间值行,无则补最大值/最小值行 if mid_q: group.append(mid_q.popleft()) else: if max_q: group.append(max_q.popleft()) else: group.append(min_q.popleft()) # 组内第三行:优先取最小值行,无则补最大值/中间值行 if min_q: group.append(min_q.popleft()) else: if max_q: group.append(max_q.popleft()) else: group.append(mid_q.popleft()) result.extend(group) # 转换为目标DataFrame sorted_df = pd.DataFrame(result).reset_index(drop=True) print(sorted_df)
逻辑说明
- 数据分类:先将原始数据按
Balance值拆分为最大值行、中间值行、最小值行三类,用队列存储以保证取数顺序。 - 组内构建:每组3行依次按规则取数:
- 第一行优先取最大值行,无则补中间值/最小值行
- 第二行优先取中间值行,无则补最大值/最小值行(符合规则中"中间值可等于极值"的要求)
- 第三行优先取最小值行,无则补最大值/中间值行
- 兼容场景:当所有值相等时,三类行合并为同一队列,每组按顺序取3行即可,满足规则要求。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

