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

基于列前缀重塑DataFrame:无循环实现列结构转换

如何在Pandas中无循环重塑宽表为指定长表结构

问题描述

我读取了一个CSV文件到DataFrame,结构如下:

TimeAP1AQ1AP2AQ2AP3AQ3AP4AQ4AP5AQ5
020001001030030500507007090090
120011051530535505557057590595
2200211020310405106071080910100
3200311525315455156571585915105
4200412030320505207072090920110
5200512535325555257572595925115

想要不使用循环将其重塑为仅包含Time、AP、AQ三列的结构,目标结构示例如下:

TimeAPAQ
0200010010
0200030030
0200050050
0200070070
0200090090
1200110515
............

解决方案

这是典型的宽表转长表需求,Pandas提供了高效的矢量化方法,完全不需要写循环,推荐两种方案:

方案1:使用pd.wide_to_long(最贴合需求)

这个方法专门为这种带有编号后缀的成对列设计,代码简洁且高效:

import pandas as pd

# 实际场景中替换为读取CSV的代码:df = pd.read_csv("your_file.csv")
data = {
    "Time": [2000, 2001, 2002, 2003, 2004, 2005],
    "AP1": [100, 105, 110, 115, 120, 125],
    "AQ1": [10, 15, 20, 25, 30, 35],
    "AP2": [300, 305, 310, 315, 320, 325],
    "AQ2": [30, 35, 40, 45, 50, 55],
    "AP3": [500, 505, 510, 515, 520, 525],
    "AQ3": [50, 55, 60, 65, 70, 75],
    "AP4": [700, 705, 710, 715, 720, 725],
    "AQ4": [70, 75, 80, 85, 90, 95],
    "AP5": [900, 905, 910, 915, 920, 925],
    "AQ5": [90, 95, 100, 105, 110, 115]
}
df = pd.DataFrame(data)

# 核心重塑代码
result = pd.wide_to_long(
    df,
    stubnames=["AP", "AQ"],  # 列名的前缀部分
    i="Time",  # 保留的标识列
    j="id",    # 后缀编号会生成的临时列(可后续删除)
    sep=""     # 前缀与后缀之间无分隔符,设为空字符串
).reset_index()

# 删除临时的id列,得到目标结构
result = result.drop("id", axis=1)

print(result.head(10))

运行后输出的前10行完全符合需求:

Time   AP   AQ
0  2000  100   10
1  2000  300   30
2  2000  500   50
3  2000  700   70
4  2000  900   90
5  2001  105   15
6  2001  305   35
7  2001  505   55
8  2001  705   75
9  2001  905   95

方案2:使用pd.melt(通用型宽转长方法)

如果你的列名规律更复杂,melt是更通用的选择,步骤稍多但同样高效:

# 拆分AP和AQ列
ap_melt = df.melt(id_vars="Time", value_vars=[col for col in df.columns if col.startswith("AP")], var_name="AP_col", value_name="AP")
aq_melt = df.melt(id_vars="Time", value_vars=[col for col in df.columns if col.startswith("AQ")], var_name="AQ_col", value_name="AQ")

# 提取列名中的编号,确保AP和AQ能一一对应
ap_melt["id"] = ap_melt["AP_col"].str.extract("(\d+)").astype(int)
aq_melt["id"] = aq_melt["AQ_col"].str.extract("(\d+)").astype(int)

# 合并两个结果并清理冗余列
result = pd.merge(ap_melt, aq_melt, on=["Time", "id"]).drop(["AP_col", "AQ_col", "id"], axis=1)

# 按Time排序,和目标结构对齐(可选)
result = result.sort_values("Time").reset_index(drop=True)

print(result.head(10))

这个方法同样能得到完全一致的结果,适合列名规则不那么规整的场景。


内容的提问来源于stack exchange,提问作者user8465900

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:32:14