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

如何使用Pandas对DataFrame每行多组O类关联字段按名称排序对齐

问题描述

现有数据集固定包含Date、Product两列,其余为多组选项字段,每组选项对应Name、Price、Qty三个属性,按O1_*、O2_*、O3_*……规则命名。原始数据存在行内错位问题:同组的三个属性不会固定落在对应编号的O列下,部分高编号O列可能为空。
需要实现逐行对齐逻辑:以每行所有选项的Name字段为排序依据,排序后将同组的Price、Qty跟随对应Name同步移动,按名称排序后依次填入O1、O2、O3……对应列位,保证同选项三个字段归属一致。

原始数据样例

Date        Product  O1_Name  O1_Price  O1_Qty  O2_Name  O2_Price  O2_Qty
05-12-2021  MK       Widget1   0.99      23     Widget2    1.50      80
05-12-2021  MK       Widget2   1.50      85     Widget1    0.99      25
05-11-2021  MK       Widget1   0.99      28     Widget2    1.50      85
05-10-2021  MK       Widget1   0.99      31     Widget2    1.50      95
05-13-2021  PS       WidgetA   0.52      49     WidgetB    0.86      43
05-12-2021  PS       WidgetA   0.52      53     WidgetB    0.86      43
05-10-2021  PS       WidgetB   0.85      66     WidgetA    0.58      60
05-13-2021  AY       WidgetZ   0.15      87     
05-12-2021  AY       WidgetZ   0.15      88     

期望输出样例

Date    Product  O1_Name  O1_Price  O1_Qty  O2_Name  O2_Price  O2_Qty
05-12-2021  MK       Widget1   0.99      23     Widget2    1.50      80
05-12-2021  MK       Widget1   0.99      25     Widget2    1.50      85
05-11-2021  MK       Widget1   0.99      28     Widget2    1.50      85
05-10-2021  MK       Widget1   0.99      31     Widget2    1.50      95
05-13-2021  PS       WidgetA   0.52      49     WidgetB    0.86      43
05-12-2021  PS       WidgetA   0.52      53     WidgetB    0.86      43
05-10-2021  PS       WidgetA   0.58      60     WidgetB    0.85      66
05-13-2021  AY       WidgetZ   0.15      87     
05-12-2021  AY       WidgetZ   0.15      88   

操作参考示意图:
Sort Horizontally


Pandas实现方案

核心思路是先拆分固定列和选项列,逐行将零散的选项字段重组为(Name, Price, Qty)的元组列表,过滤空值后按Name排序,再展开回原列结构即可,自动兼容O3、O4等任意数量的选项列。

完整可运行代码

import pandas as pd
import numpy as np

# 此处替换为你自己的数据读取逻辑,比如pd.read_excel、pd.read_csv
raw_data = [
    ["05-12-2021", "MK", "Widget1", 0.99, 23, "Widget2", 1.50, 80],
    ["05-12-2021", "MK", "Widget2", 1.50, 85, "Widget1", 0.99, 25],
    ["05-11-2021", "MK", "Widget1", 0.99, 28, "Widget2", 1.50, 85],
    ["05-10-2021", "MK", "Widget1", 0.99, 31, "Widget2", 1.50, 95],
    ["05-13-2021", "PS", "WidgetA", 0.52, 49, "WidgetB", 0.86, 43],
    ["05-12-2021", "PS", "WidgetA", 0.52, 53, "WidgetB", 0.86, 43],
    ["05-10-2021", "PS", "WidgetB", 0.85, 66, "WidgetA", 0.58, 60],
    ["05-13-2021", "AY", "WidgetZ", 0.15, 87, np.nan, np.nan, np.nan],
    ["05-12-2021", "AY", "WidgetZ", 0.15, 88, np.nan, np.nan, np.nan],
]
columns = ["Date", "Product", "O1_Name", "O1_Price", "O1_Qty", "O2_Name", "O2_Price", "O2_Qty"]
df = pd.DataFrame(raw_data, columns=columns)

# 拆分固定列和选项列
fixed_cols = ["Date", "Product"]
opt_cols = [c for c in df.columns if c not in fixed_cols]
# 自动识别所有O开头的选项编号,兼容O3/O4等任意数量选项
opt_nums = sorted(list(set([c.split("_")[0] for c in opt_cols])), key=lambda x: int(x[1:]))
fixed_df = df[fixed_cols].copy()
opt_df = df[opt_cols].copy()

# 逐行对齐选项
def align_row_opts(row):
    # 组装(Name, Price, Qty)元组,跳过Name为空的无效选项
    opt_tuples = []
    for o_num in opt_nums:
        name = row[f"{o_num}_Name"]
        if pd.isna(name) or str(name).strip() == "":
            continue
        price = row[f"{o_num}_Price"]
        qty = row[f"{o_num}_Qty"]
        opt_tuples.append((name, price, qty))
    # 按Name字段排序
    opt_tuples.sort(key=lambda x: x[0])
    # 补全空位,匹配原列长度
    while len(opt_tuples) < len(opt_nums):
        opt_tuples.append((np.nan, np.nan, np.nan))
    # 展开为一维数组,对应原列顺序
    res = []
    for i, o_num in enumerate(opt_nums):
        res.extend([opt_tuples[i][0], opt_tuples[i][1], opt_tuples[i][2]])
    return res

# 应用处理逻辑,拼接回最终结果
aligned_opt = opt_df.apply(align_row_opts, axis=1, result_type="expand")
aligned_opt.columns = opt_cols
result = pd.concat([fixed_df, aligned_opt], axis=1)

print(result)

方案说明

  • 无需手动指定选项数量,代码自动识别所有O*_Name/Price/Qty格式的列,支持任意多组选项场景
  • 自动跳过Name为空的无效选项,排序后空值自动填充到序号靠后的O列,不会打乱有效选项顺序
  • 处理过程中始终将Price、Qty和对应Name绑定移动,不会出现字段归属错配
  • 代码运行后输出结果和给出的期望样例完全一致

内容的提问来源于stack exchange,提问作者SG Fresh Idea

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 00:36:28