Python中如何正确透视Pandas DataFrame?现有代码未达预期
Pandas DataFrame 透视转换解决方案
问题分析
从你提供的代码来看,你试图处理带有分组标识行的DataFrame(分组行的4列非数字,明细行是数字),并将其转换为规整的透视格式,但原代码的逻辑存在拼接错误,导致结果不符合预期。
正确实现步骤
以下是针对这类场景的通用解决方案,分两种常见目标格式处理:
场景1:将分组信息合并到明细行(基础规整)
假设你的原始DataFrame是分组行+明细行的结构(比如分组行存放组名,下方是该组的明细数据),首先需要把分组信息填充到对应的明细行,再过滤掉冗余的分组行:
import pandas as pd # 1. 标记明细行(`4`列匹配数字的行) is_detail = df['4'].str.match(r'\d', na=False) # 2. 提取分组行的标识(假设组名在第0列),向下填充到所有明细行 df['分组'] = df.loc[~is_detail, 0].ffill() # 3. 只保留明细行,重置索引 df_clean = df[is_detail].reset_index(drop=True)
场景2:透视成宽表(多行转多列)
如果你的目标是把每个分组的多行明细转为一行多列,可以在上面的基础上,结合groupby和pivot实现:
# 给每个分组内的明细行添加序号 df_clean['行序号'] = df_clean.groupby('分组').cumcount() + 1 # 按分组透视,将明细行转成列 pivoted_df = df_clean.pivot( index='分组', columns='行序号', values=df_clean.columns.drop(['分组', '行序号']) ) # 整理列名(比如将(列名, 序号)转为`列名_序号`格式) pivoted_df.columns = pivoted_df.columns.map(lambda x: f'{x[0]}_{x[1]}') # 重置索引,让分组成为普通列 pivoted_df = pivoted_df.reset_index()
原代码问题说明
你原代码的逻辑错误在于:
df.where(m, axis=0).ffill()[~m]是将分组行的信息填充后,再提取非明细行(即分组行),这一步方向搞反了;- 后续
join(df[~m])重复拼接了分组行数据,导致列结构混乱,最终结果不符合预期。
内容的提问来源于stack exchange,提问作者Lok
相关产品推荐
相关产品推荐

