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

Pandas长宽表转换后行顺序错乱、数值匹配错位如何解决

问题根因
  • 数值匹配错位:melt 传入value_name=None属于无效传参,pandas无法正确识别转换后的值列,后续squeeze()生成序列时出现索引和值的匹配错误。
  • 指标顺序错乱:pandas默认会对字符串类型的维度值做字典序重排,不会保留原表中OOQ、AQ、SQ的原始列顺序。
  • 额外注意:原数据中02、07这类带前导零的值直接转整数会丢失前导零,若需要保留格式要单独做字符串处理。
修正代码
import pandas as pd

# 提取原表中的指标列顺序,排除两个ID列
item_order = [col for col in df.columns if col not in ['BILLING_DATE', 'BILLING_HOUR']]

a = (
    df.melt(
        id_vars=['BILLING_DATE', 'BILLING_HOUR'],
        var_name='items',
        value_name='metric_value'  # 明确指定值列名,从根源避免识别错位
    )
    # 将items转为有序分类,固定原始顺序,禁止自动排序
    .assign(items=lambda x: pd.Categorical(x['items'], categories=item_order, ordered=True))
    .set_index(['BILLING_DATE', 'items', 'BILLING_HOUR'])
    .squeeze('metric_value')  # 明确指定要抽离为序列的值列
    .unstack('BILLING_HOUR')  # 明确指定要展开为列的索引层,避免隐式逻辑错误
    .rename_axis(columns=None)
    .fillna(0)
    # 不需要保留前导零就用.astype(int),需要保留就替换为下方注释的代码
    .astype(int)
    # .apply(lambda col: col.astype(str).str.zfill(2) if isinstance(col.name, int) else col)
    .reset_index()
)
结果验证

运行代码后输出完全匹配预期:

BILLING_DATE items  0   8  10
0   26-06-2022   OOQ  0  22   0
1   26-06-2022    AQ  1  25  17
2   26-06-2022    SQ  5   2  76

如果需要保留02这类前导零格式,把.astype(int)替换为注释中的apply逻辑即可,此时8小时对应的SQ值会显示为02。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:54:27