Python Pandas:如何更简便地实现指定格式的DataFrame转换?
Pandas 行列转换的简便实现方法
问题场景
初始DataFrame定义如下:
import pandas as pd df = pd.DataFrame({'Animal': ['Falcon', 'Falcon', 'Parrot', 'Parrot'], 'Max Speed': [380., 370., 24., 26.]})
对应的初始数据结构:
Animal Max Speed 0 Falcon 380.0 1 Falcon 370.0 2 Parrot 24.0 3 Parrot 26.0
需要将其转换为以动物名称为列名、对应速度值按行排列的结构:
Falcon Parrot 0 380 24 1 370 26
用户最初尝试用groupby实现但未找到简便方式,自行实现的代码较为繁琐:
df.groupby('Animal')['Max Speed'].apply(pd.DataFrame).apply(lambda x: pd.Series(x.dropna().to_numpy()))
更优实现方案
方案1:直接使用pivot(最简洁)
pivot是处理此类行列转换的原生工具,一步到位:
result = df.pivot(columns='Animal', values='Max Speed').reset_index(drop=True)
columns='Animal':将Animal列的唯一值设为新DataFrame的列名values='Max Speed':指定填充新列的数据来源reset_index(drop=True):清除原索引,生成从0开始的连续索引
方案2:groupby.cumcount + pivot(兼容数据量不一致场景)
如果存在不同动物的速度数据量不一致的情况,可先给每个动物分组内的行添加序号,再做转换,确保数据按顺序对齐:
# 给每个动物分组内的行添加递增序号 df['row_num'] = df.groupby('Animal').cumcount() # 按序号和动物名称做透视转换 result = df.pivot(index='row_num', columns='Animal', values='Max Speed').reset_index(drop=True)
这种方式会对缺失的行自动填充NaN,保证结构规整。
方案3:groupby + unstack
利用分组后拆分层级的方式实现转换:
result = df.groupby(['Animal', df.groupby('Animal').cumcount()])['Max Speed'].unstack(0).reset_index(drop=True)
- 先按
Animal和分组内序号双重分组 unstack(0)将Animal层级从索引转为列
以上三种方案都比原实现更简洁高效,避免了嵌套apply带来的性能损耗,代码可读性也更强。
内容的提问来源于stack exchange,提问作者pandasPythonQuestion
相关产品推荐
相关产品推荐

