You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按District列的值均匀重排行数不均的DataFrame?

按分组均匀重排DataFrame行(解决长度不匹配问题)

问题描述

现有一个随机生成的Pandas DataFrame,District列的各分组行数存在差异(如示例中alpha有10行、bravo有4行、charlie有9行),需要按District的值对行进行均匀穿插重排,但尝试的方法均出现长度不匹配错误。

输入示例:

Region District  A   B ...
--------------------------
  x      alpha   1   4 ...
  x      alpha   2   3 ...
  x      alpha   3   4 ...
  x      alpha   4   3 ...
  x      alpha   5   4 ...
  x      alpha   6   4 ...
  x      alpha   7   3 ...
  x      alpha   8   4 ...
  x      alpha   9   3 ...
  x      alpha   10  4 ...
  x      bravo   11  3 ...
  x      bravo   12  4 ...
  x      bravo   13  3 ...
  x      bravo   14  3 ...
  x    charlie   15  4 ...
  x    charlie   16  3 ...
  x    charlie   17  4 ...
  x    charlie   18  3 ...
  x    charlie   19  4 ...
  x    charlie   20  3 ...
  x    charlie   21  4 ...
  x    charlie   22  3 ...
  x    charlie   23  4 ...

期望输出(均匀穿插各组行):

Region District  A   B ...
--------------------------
  x      alpha   1   4 ...
  x      alpha   2   3 ...
  x      bravo   11  3 ...
  x    charlie   15  4 ...
  x    charlie   16  3 ...
  x      alpha   3   4 ...
  x      alpha   4   3 ...
  x      bravo   12  4 ...
  x    charlie   17  4 ...
  x    charlie   18  3 ...
  x      alpha   5   4 ...
  x      alpha   6   4 ...
  x      bravo   13  3 ...
  x    charlie   19  4 ...
  x    charlie   20  3 ...
  x      alpha   7   3 ...
  x      alpha   8   4 ...
  x      bravo   14  3 ...
  x    charlie   21  4 ...
  x    charlie   22  3 ...
  x      alpha   9   3 ...
  x      alpha   10  4 ...
  x    charlie   21  4 ...
  x    charlie   22  3 ...
  x    charlie   23  4 ...

核心问题分析

普通的zip或concat方法会因分组长度不一致报错:

  • zip会在最短分组结束后停止,丢弃长分组的剩余行;
  • zip_longest会填充None,导致DataFrame列值不匹配。

解决方案

方法一:分组加批次号排序(推荐,简洁高效)

通过给每个分组内的行分配批次ID,再按批次ID排序,实现均匀穿插,完全避免长度不匹配问题。

代码实现

import pandas as pd

# 构造示例DataFrame(可替换为你的数据)
data = {
    'Region': ['x']*23,
    'District': ['alpha']*10 + ['bravo']*4 + ['charlie']*9,
    'A': list(range(1,24)),
    'B': [4,3,4,3,4,4,3,4,3,4] + [3,4,3,3] + [4,3,4,3,4,3,4,3,4]
}
df = pd.DataFrame(data)

# 1. 定义每个分组的单次取数步长(可根据需求调整,示例匹配期望输出)
step_dict = {'alpha': 2, 'bravo': 1, 'charlie': 2}
# 2. 定义分组的排序优先级(控制同一批次内的分组顺序)
district_order = ['alpha', 'bravo', 'charlie']

# 3. 给每行添加批次ID
df['batch_id'] = df.groupby('District').apply(
    lambda g: g.index.to_series().apply(lambda x: (x - g.index[0]) // step_dict[g.name])
).reset_index(level=0, drop=True)

# 4. 给分组添加排序键(保证同一批次内的分组顺序)
df['district_sort'] = df['District'].map(lambda x: district_order.index(x))

# 5. 排序并清理临时列
result = df.sort_values(by=['batch_id', 'district_sort']).drop(columns=['batch_id', 'district_sort'])

# 查看结果
print(result)

通用适配(自动计算步长)

如果不需要手动指定步长,可根据各组长度比例自动计算:

# 计算各组长度
group_sizes = df.groupby('District').size()
# 按最小分组长度计算步长,保证每个批次的循环次数匹配最小分组
step_dict = (group_sizes // group_sizes.min()).to_dict()

方法二:迭代器循环取数(直观灵活)

通过迭代器循环从每个分组中取指定数量的行,直到所有行取完,完全规避长度不匹配问题。

代码实现

import pandas as pd

# 构造示例DataFrame
data = {
    'Region': ['x']*23,
    'District': ['alpha']*10 + ['bravo']*4 + ['charlie']*9,
    'A': list(range(1,24)),
    'B': [4,3,4,3,4,4,3,4,3,4] + [3,4,3,3] + [4,3,4,3,4,3,4,3,4]
}
df = pd.DataFrame(data)

# 定义分组顺序和单次取数步长
district_order = ['alpha', 'bravo', 'charlie']
step_dict = {'alpha': 2, 'bravo': 1, 'charlie': 2}

# 按分组拆分DataFrame并转换为迭代器
groups = [df[df['District'] == d] for d in district_order]
iters = [iter(g.itertuples(index=False, name=None)) for g in groups]
step_list = [step_dict[d] for d in district_order]

result_rows = []

# 循环取数直到所有迭代器为空
while True:
    has_rows = False
    for it, step in zip(iters, step_list):
        for _ in range(step):
            try:
                row = next(it)
                result_rows.append(row)
                has_rows = True
            except StopIteration:
                continue
    if not has_rows:
        break

# 转换为DataFrame
result = pd.DataFrame(result_rows, columns=df.columns)
print(result)

效果验证

两种方法均能生成符合期望的均匀重排结果,且不会出现长度不匹配错误,适配任意分组长度差异的场景。

内容的提问来源于stack exchange,提问作者A.H

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 15:01:19