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

Pandas实现单行多列键值对转换为多行(1:n)

解决DataFrame多组键值对转多行的问题

嘿,这个重塑DataFrame的需求太常见了!咱们直接用Pandas的工具来搞定,分两种情况给你演示,不管你有多少前置列、多少组键值对都能hold住。

方法一:用wide_to_long(最适合规律列名)

这个函数专门为这种“前缀+数字”的列名设计,比如你的key1/value1、key2/value2,用它最省心。

先处理你的示例数据

import pandas as pd
# 你的原始DataFrame
values = [['John', 'somekey1', 'somevalue1', 'somekey2', 'somevalue2']]
df = pd.DataFrame(values, columns=['name', 'key1', 'value1', 'key2', 'value2'])

# 核心转换代码
df_long = pd.wide_to_long(
    df,
    stubnames=['key', 'value'],  # 列名的前缀部分
    i='name',  # 需要保留的前置列(如果有多个就用列表,比如['name', 'age'])
    j='pair_num',  # 生成的用来标记第几组键值对的列名
    sep=''  # 前缀和数字之间的分隔符,这里没有分隔符所以用空字符串
).reset_index().dropna(subset=['key', 'value'])  # 重置索引,过滤可能的空值

print(df_long)

运行后输出就是你要的多行格式:

name  pair_num       key       value
0   John         1  somekey1  somevalue1
1   John         2  somekey2  somevalue2

扩展到多前置列的情况

如果你的原始数据还有其他前置列(比如age、gender),只需要把所有前置列放到i参数的列表里就行:

# 模拟多前置列的场景
values = [['John', 30, 'Male', 'somekey1', 'somevalue1', 'somekey2', 'somevalue2', 'somekey3', 'somevalue3']]
df = pd.DataFrame(values, columns=['name', 'age', 'gender', 'key1', 'value1', 'key2', 'value2', 'key3', 'value3'])

# 转换代码
df_long = pd.wide_to_long(
    df,
    stubnames=['key', 'value'],
    i=['name', 'age', 'gender'],  # 所有前置列都放这里
    j='pair_num',
    sep=''
).reset_index().dropna(subset=['key', 'value'])

print(df_long)

输出会保留所有前置列,同时把每组键值对拆成单独一行:

name  age gender  pair_num       key       value
0   John   30   Male         1  somekey1  somevalue1
1   John   30   Male         2  somekey2  somevalue2
2   John   30   Male         3  somekey3  somevalue3

方法二:用melt(更灵活,适合列名不那么规律的情况)

如果你的键值对列名不是严格的keyN/valueN格式,或者需要更灵活的处理,可以用melt来拆分后合并:

# 还是用你的示例DataFrame
import pandas as pd
values = [['John', 'somekey1', 'somevalue1', 'somekey2', 'somevalue2']]
df = pd.DataFrame(values, columns=['name', 'key1', 'value1', 'key2', 'value2'])

# 第一步:分离前置列和键值对列
id_vars = [col for col in df.columns if not col.startswith('key') and not col.startswith('value')]
key_cols = [col for col in df.columns if col.startswith('key')]
value_cols = [col.replace('key', 'value') for col in key_cols]

# 第二步:分别拆分key列和value列
df_keys = df.melt(id_vars=id_vars, value_vars=key_cols, var_name='pair_num', value_name='key')
df_values = df.melt(id_vars=id_vars, value_vars=value_cols, var_name='pair_num', value_name='value')

# 第三步:合并拆分后的结果
df_long = pd.merge(df_keys, df_values, on=id_vars + ['pair_num'])
# 可选:清理pair_num列,去掉前缀
df_long['pair_num'] = df_long['pair_num'].str.replace('key', '')

print(df_long)

这个方法也能得到和第一种方法一样的结果,适合列名规则不太统一的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:40:28