求助:Pandas中如何将成对key_/value_列转为key-value行结构
如何重塑包含成对key/value列的DataFrame?
你已经用melt迈出了正确的第一步,但确实还需要把成对的key_n和value_n对应起来。核心思路是找到每对字段的共同数字标识(也就是列名里的1、2...n),以此为桥梁把key和value配对。
下面给你两种可行的解决方案,附带详细解释:
方法一:拆分后合并(直观易理解)
步骤1:处理melt后的结果,提取配对标识
先从variable列里提取数字后缀,作为每对key/value的匹配键:
import pandas as pd # 模拟你的原始数据 df = pd.DataFrame({ 'firstid': [1], 'secondid': ['one'], 'key_1': ['A'], 'key_2': ['B'], 'key_3': ['C'], 'value_1': ['alpha'], 'value_2': ['beta'], 'value_3': ['gamma'] }) # 你原来的melt操作 value_vars = [x for x in df.columns if x.startswith('key_') or x.startswith('value_')] melted_df = pd.melt(df, id_vars=["firstid", "secondid"], value_vars=value_vars) # 提取数字后缀作为配对索引 melted_df['pair_idx'] = melted_df['variable'].str.extract(r'(\d+)')
步骤2:拆分key和value数据集
把melt后的结果分成key组和value组,并重命名列:
# 筛选key行,并重命名value列为key key_df = melted_df[melted_df['variable'].str.startswith('key_')].rename(columns={'value': 'key'}) # 筛选value行,保留原value列名 value_df = melted_df[melted_df['variable'].str.startswith('value_')]
步骤3:按共同标识合并
用firstid、secondid和pair_idx作为合并键,把两组数据拼在一起,最后清理冗余列:
result = pd.merge( key_df[['firstid', 'secondid', 'pair_idx', 'key']], value_df[['firstid', 'secondid', 'pair_idx', 'value']], on=['firstid', 'secondid', 'pair_idx'] ).drop('pair_idx', axis=1) # 重命名列(可选,和你想要的格式完全匹配) result = result.rename(columns={'firstid': 'first_id', 'secondid': 'second_id'})
方法二:用pivot更简洁实现
如果想少写几行代码,可以利用pivot直接把key和value转成列,再展开:
# 延续上面的melted_df # 拆分variable列为类型(key/value)和配对索引 melted_df[['type', 'pair_idx']] = melted_df['variable'].str.split('_', expand=True) # 按id列和pair_idx做pivot,把type转成列 pivoted = melted_df.pivot( index=['firstid', 'secondid', 'pair_idx'], columns='type', values='value' ).reset_index() # 清理列名和冗余列 result = pivoted.drop('pair_idx', axis=1).rename(columns={'firstid': 'first_id', 'secondid': 'second_id'})
两种方法最终都会得到你想要的格式:
| first_id | second_id | key | value |
|---|---|---|---|
| 1 | one | A | alpha |
| 1 | one | B | beta |
| 1 | one | C | gamma |
核心逻辑都是利用列名里的数字后缀建立key和value的对应关系,不管n是多少,只要key和value的数量相等,这个方法就通用。
内容的提问来源于stack exchange,提问作者Ettore Rizza
相关产品推荐
相关产品推荐

