如何用Pandas实现带列名拆分的表格透视转换?
解决DataFrame列名按第三个英文句号拆分并透视的问题
我有一个指定结构的DataFrame,需要将列名中第三个英文句号之后的部分拆分出来作为新列(例如Car、Food),第三个句号之前的内容作为Trait列,再通过透视转换得到目标格式的输出。预期输出会因透视增加行数,且该逻辑需要适用于任意带多段点分隔的列名。我尝试了一段代码但未得到预期结果,代码如下:
import pandas as pd data = { 'GenoType': [1, 2, 4], 'Parameter1': [2, 2, 787], 'First.Second.Third.Car': ['Honda', 'Tesla', 'Jeep'], 'First.Second.Third.Food': ['Pizza', 'Fries', 'Grapes'], 'Red.Orange.Yellow.Car': ['Acura', 'BMW', 'Toyota'], 'Red.Orange.Yellow.Food': ['Burger', 'Potatoes', 'Wings'] } df = pd.DataFrame(data) melted_df = df.melt(id_vars=['GenoType', 'Parameter1'], var_name='Trait', value_name='Value') melted_df[['Trait', 'Column']] = melted_df['Trait'].str.rsplit('.', n=1, expand=True) pivoted_df = melted_df.pivot_table(index=['GenoType', 'Parameter1', 'Trait'], columns='Column', values='Value', aggfunc='first') pivoted_df.reset_index(inplace=True) pivoted_df.columns.name = '' # Melt the pivoted_df to obtain the final output final_df = pivoted_df.melt(id_vars=['GenoType', 'Parameter1', 'Trait'], var_name='Column', value_name='Value') final_df.sort_values(by=['GenoType', 'Parameter1', 'Trait', 'Column'], inplace=True) final_df.reset_index(drop=True, inplace=True) expanded_df = final_df.pivot_table(index=['GenoType', 'Parameter1', 'Trait'], columns='Column', values='Value', aggfunc='first') expanded_df.reset_index(inplace=True) expanded_df.columns.name = '' expanded_df = expanded_df.rename_axis(None, axis=1) print(expanded_df)
问题分析
当前代码的核心问题是使用rsplit('.', n=1)从列名末尾拆分最后一个点,而非按第三个点拆分,这与需求不符。正确的做法是按第三个句号拆分列名,提取对应部分分别作为Trait和新列标识。
修正后的代码
import pandas as pd data = { 'GenoType': [1, 2, 4], 'Parameter1': [2, 2, 787], 'First.Second.Third.Car': ['Honda', 'Tesla', 'Jeep'], 'First.Second.Third.Food': ['Pizza', 'Fries', 'Grapes'], 'Red.Orange.Yellow.Car': ['Acura', 'BMW', 'Toyota'], 'Red.Orange.Yellow.Food': ['Burger', 'Potatoes', 'Wings'] } df = pd.DataFrame(data) # 将非ID列转为长格式,保留原始完整列名 melted_df = df.melt(id_vars=['GenoType', 'Parameter1'], var_name='Full_Trait', value_name='Value') # 按第三个句号拆分完整列名,得到4个部分 split_result = melted_df['Full_Trait'].str.split('.', n=3, expand=True) # 前三个部分拼接为Trait列,第四个部分作为新列的标识 melted_df['Trait'] = split_result[0] + '.' + split_result[1] + '.' + split_result[2] melted_df['Column'] = split_result[3] # 透视得到目标宽格式 final_df = melted_df.pivot_table( index=['GenoType', 'Parameter1', 'Trait'], columns='Column', values='Value', aggfunc='first' ).reset_index() # 清除列名的层级标签 final_df.columns.name = '' print(final_df)
代码说明
- 列名拆分:用
str.split('.', n=3)将完整列名最多拆分3次,得到4个分段。前三个分段拼接成Trait列,第四个分段作为Column列(即Car、Food这类标识)。 - 透视转换:以
GenoType、Parameter1、Trait为索引,Column为列,Value为数据值进行透视,aggfunc='first'保证每个索引-列组合只取唯一值(适配原始数据的结构)。 - 格式整理:重置索引并清空列名的层级名称,输出符合需求的结构化DataFrame。
内容的提问来源于stack exchange,提问作者Void S
相关产品推荐
相关产品推荐

