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

如何将Pandas长格式DataFrame转换为宽格式?求解缺失步骤

Pandas长转宽:补全你的转换步骤

咱们先理清楚你的问题:你现在有一个长格式的DataFrame,想要转成宽格式,但卡在了unstack的步骤,而且前面的一些操作其实是多余的。我先把你的原始数据列出来,再一步步给你补全正确的转换逻辑。

首先,先确认你的原始数据:

import pandas as pd

d = {'vote': [100, 50,1,23,55,67,89,44], 'vote2': [10, 2,18,26,77,99,9,40], 'ballot1': ['a','b','a','a','b','a','a','b'], 'voteId':[1,2,3,4,5,6,7,8]}
df1 = pd.DataFrame(d)

这个DataFrame的结构是每个voteId对应一条记录,包含vote、vote2和ballot1(取值a或b)。

你现有代码的问题

你之前写的:

dftemp=pd.DataFrame(dftemp.reset_index())
dflw= dftemp.set_index(['voteId','vote','ballot1'])
dflw=dflw.unstack(...)

这里有几个没必要的操作和遗漏的点:

  1. 多余的reset_index:voteId已经是唯一标识,不需要额外引入默认的索引列,反而会干扰后续的索引设置。
  2. 错误的索引设置:把vote放进了索引里,这样unstack后,vote会成为行索引的一部分,无法得到你想要的宽格式结构。
  3. 未指定unstack的层级:必须告诉Pandas要把哪个索引层级转成列(这里应该是ballot1)。

两种常见的宽格式转换方案

方案1:只转换vote列,按ballot1分列

如果你的目标是每个voteId一行,把ballot1的a和b作为列展示vote的值,用pivot最直观:

# 行:voteId,列:ballot1的取值,值:vote列的数据
df_wide = df1.pivot(index='voteId', columns='ballot1', values='vote')
# 重命名列,让可读性更强
df_wide.columns = [f'vote_{col}' for col in df_wide.columns]
# 把voteId从索引转回普通列
df_wide = df_wide.reset_index()

得到的结果大概是:

voteIdvote_avote_b
1100NaN
2NaN50
31NaN
.........

如果你坚持想用set_index + unstack的方式,正确写法是:

# 只把voteId和ballot1设为索引,只保留vote列
dflw = df1.set_index(['voteId', 'ballot1'])['vote']
# 指定unstack的层级是ballot1,把它转成列
df_wide = dflw.unstack(level='ballot1')
# 后续重命名列、重置索引和上面一样
df_wide.columns = [f'vote_{col}' for col in df_wide.columns]
df_wide = df_wide.reset_index()

方案2:同时转换vote和vote2列

如果想把vote和vote2都按ballot1分列,需要先把数据“熔”成更长的格式,再转宽:

# 第一步:把vote和vote2合并成一个指标列
df_melted = df1.melt(
    id_vars=['voteId', 'ballot1'],  # 保留的标识列
    var_name='vote_type',           # 新的指标列名
    value_name='value'              # 数值列名
)

# 第二步:转成宽格式,行是voteId,列是ballot1+vote_type的组合
df_wide = df_melted.pivot(
    index='voteId',
    columns=['ballot1', 'vote_type'],
    values='value'
)

# 把多层列名扁平化,方便阅读
df_wide.columns = [f'{col[1]}_{col[0]}' for col in df_wide.columns]
df_wide = df_wide.reset_index()

最终结果的列会是vote_a、vote_b、vote2_a、vote2_b,每个voteId对应一行完整的数据。

总结你遗漏的关键步骤

  • 去掉多余的reset_index操作,避免引入无关列。
  • 设置索引时只保留行标识列(voteId)和要转成列的分组列(ballot1),不要把数值列放进索引。
  • 调用unstack时明确指定要转换的层级(比如unstack('ballot1'))。
  • 可选但推荐:重命名列和重置索引,让最终的宽格式更易读。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:38:01