如何透视DataFrame且不丢失重复值,并按reps从小到大排列列?
问题描述
输入DataFrame
id value reps 1 333 1 1 332 4 1 335 1 4 555 3 4 225 1 444 2 5
目标格式
需要按reps列从小到大排序后,将value拆分为多列,最终格式如下:
id col1 col2 col3 col4 1 333 335 332 nan 4 225 555 nan nan 444 2 nan nan nan
尝试的方法及问题
使用pivot_table方法:
dataframe = dataframe.pivot_table(index='id', columns='reps', values='value') dataframe = dataframe.rename_axis(columns=None).reset_index()
得到的结果是聚合后的DataFrame,不符合需求:
id 1 3 4 5 1 334 nan 332 nan 4 225.5 555.5 nan nan 444 nan nan nan 2
请问如何实现目标格式?
解决方案
问题出在pivot_table默认会对重复的行列组合做聚合(默认取均值),而我们需要保留所有原始值并按reps排序后展开。可以按以下步骤实现:
- 按
id和reps排序:先对DataFrame按id分组内的reps从小到大排序,确保后续展开的顺序正确。 - 生成组内序号:在每个
id分组内,为排序后的行生成连续的序号(从1开始),作为后续列的标识。 - 透视转换:用
pivot方法(而非pivot_table)根据id和组内序号来透视,避免自动聚合。 - 重命名列名:将生成的列名改为
col1、col2这类格式,并重置索引。
具体代码如下:
import pandas as pd # 原始数据 df = pd.DataFrame({ 'id': [1,1,1,4,4,444], 'value': [333,332,335,555,225,2], 'reps': [1,4,1,3,1,5] }) # 按id和reps排序 df_sorted = df.sort_values(by=['id', 'reps']) # 生成组内连续序号 df_sorted['col_num'] = df_sorted.groupby('id').cumcount() + 1 # 透视转换 result = df_sorted.pivot(index='id', columns='col_num', values='value') # 重命名列并重置索引 result = result.rename(columns=lambda x: f'col{x}').reset_index() print(result)
运行后输出结果:
id col1 col2 col3 col4 0 1 333.0 335.0 332.0 NaN 1 4 225.0 555.0 NaN NaN 2 444 2.0 NaN NaN NaN
如果需要将数值转为整数格式(缺失值保留为NaN),可添加以下代码:
result = result.astype({'col1': 'Int64', 'col2': 'Int64', 'col3': 'Int64', 'col4': 'Int64'})
内容的提问来源于stack exchange,提问作者Kevin Yorney Guzman Hernandez
相关产品推荐
相关产品推荐

