如何在pandas中将列属性转换为行属性实现表格结构转换
Pandas宽表转指定结构实现方案
核心逻辑是拆分原始数值列和zscore列,分别调整结构后按规则拼接排序,无需调用复杂的长宽表转换函数,逻辑直白易调整。
步骤1:读取/构造原始数据
首先确保原始数据读入后,第一列a.age被设为行索引,列名和示例匹配:
import pandas as pd # 以下为示例输入数据,实际使用时替换为你的数据读取代码即可,比如pd.read_excel、pd.read_csv df = pd.DataFrame( data=[ [0.973257, 0.943649, 1.547537, 0.980226], [0.960501, 0.921949, -0.242228, 0.017680] ], index=pd.Index(['15-20', '21-34'], name='a.age'), columns=['829', '1030', '829_zscore', '1030_zscore'] )
步骤2:通用结构转换代码
以下代码无需硬编码列名,会自动识别带_zscore后缀的列,适配任意数量的数值分组列:
# 自动识别zscore列、对应的原始值列 zscore_cols = [col for col in df.columns if col.endswith('_zscore')] raw_cols = [col.replace('_zscore', '') for col in zscore_cols] # 提取原始值部分,保留原有行列结构 df_raw = df[raw_cols].copy() # 调整zscore部分结构:列名对齐原始列,行索引加_zscore后缀 df_zscore = df[zscore_cols].copy() df_zscore.columns = raw_cols df_zscore.index = [f'{idx}_zscore' for idx in df_zscore.index] # 纵向拼接两部分数据 df_res = pd.concat([df_raw, df_zscore], axis=0) # 调整行顺序,保证同一年龄组的原始值、zscore值相邻 sort_order = [] for age_group in df.index: sort_order.extend([age_group, f'{age_group}_zscore']) df_res = df_res.reindex(sort_order)
注:如果需要和示例里的
15_20_zscore格式完全匹配(把年龄组里的-替换为_),只需要把生成zscore行索引的代码改成df_zscore.index = [f'{idx.replace("-", "_")}_zscore' for idx in df_zscore.index],同步调整排序规则里的对应索引值即可。
结果验证
执行print(df_res)即可得到和期望完全一致的输出:
829 1030 a.age 15-20 0.973257 0.943649 15-20_zscore 1.547537 0.980226 21-34 0.960501 0.921949 21-34_zscore -0.242228 0.017680
如果需要把行索引a.age转回普通列,追加一行df_res = df_res.reset_index()即可。
内容的提问来源于stack exchange,提问作者Nabih Bawazir
相关产品推荐
相关产品推荐

