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

Pandas DataFrame转换:如何实现unpivot(逆透视)操作?

当然可以用逆透视实现这个转换!

你的需求是把宽表结构的DataFrame转换成标准的长表结构,逆透视(Unpivot)正是干这个的活儿~在Pandas里,有两个常用方法可以轻松搞定:wide_to_long(适合列名有规律的场景)和melt(更通用的方法)。

先构造你的原始数据

首先我们先还原你给出的DataFrame:

import pandas as pd

df = pd.DataFrame({
    'commune': ['A', 'B', 'C'],
    'nuance_1': ['X', 'X', 'Z'],
    'votes_1': [12, 10, 7],
    'nuance_2': ['Y', 'Y', 'X'],
    'votes_2': [20, 5, 2],
    'nuance_3': ['Z', None, None],
    'votes_3': [5, None, None]
})

方法1:用wide_to_long(最贴合你的列名结构)

因为你的列都是nuance_n和votes_n的命名规律,wide_to_long专门处理这种带序号后缀的宽表,代码非常简洁:

# 执行逆透视操作
df_long = pd.wide_to_long(
    df,
    stubnames=['nuance', 'votes'],  # 指定要拆分的列前缀
    i='commune',  # 保留的唯一标识列
    j='seq',  # 拆分后生成的序号列(可以随便命名)
    sep='_'  # 列名里的分隔符
).dropna()  # 去掉空值行(比如B、C的第三组数据是空的)
# 整理索引和列顺序
df_long = df_long.reset_index(drop=True)[['commune', 'nuance', 'votes']]

执行后得到的结果就是你想要的结构:

communenuancevotes
AX12
AY20
AZ5
BX10
BY5
CZ7
CX2

方法2:用melt(更通用的逆透视方法)

如果你的列名没有那么规整,melt是更通用的选择。我们可以分别对nuance和votes列做逆透视,再合并结果:

# 拆分nuance列
nuance_df = df.melt(
    id_vars='commune',
    value_vars=['nuance_1', 'nuance_2', 'nuance_3'],
    var_name='seq',
    value_name='nuance'
)
# 拆分votes列
votes_df = df.melt(
    id_vars='commune',
    value_vars=['votes_1', 'votes_2', 'votes_3'],
    var_name='seq',
    value_name='votes'
)
# 合并并清理数据
df_long = pd.merge(nuance_df, votes_df, on=['commune', 'seq']) \
           .dropna() \
           .drop('seq', axis=1) \
           .sort_values('commune') \
           .reset_index(drop=True)

这个方法也能得到完全一样的结果,只是步骤稍多一点。

总结

完全可以通过逆透视实现这个转换!Pandas的这两个方法都是专门为宽表转长表设计的,根据你的列名结构选择对应的方法就好~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 10:57:30