Python Pandas:如何高效实现垂直数据到水平数据的转换?
更高效的Pandas DataFrame转换方案
嘿,你的这个需求完全可以用Pandas的内置分组+透视功能来实现,比手动遍历简洁太多,而且是向量化操作,数据量大的时候速度优势会特别明显!
核心思路
我们可以通过给每个Reference_id组内的成员生成序号,然后将长表格式的Name列重塑为宽表,最后关联回对应的Person_ID即可,全程不用手动循环。
完整实现代码
首先先还原你的原始DataFrame:
import pandas as pd person_id = [1,2,3,4,5] reference_id = [1,1,1,4,9] name = ['Max','Kevin','Sara',"Chessi","Fernando"] list_tuples=list(zip(person_id,reference_id,name)) old_dataframe = pd.DataFrame(list_tuples,columns=['Person_ID','Reference_id','Name'])
接下来是转换步骤:
给每个组内的成员生成序号列
我们用groupby.cumcount()给每个Reference_id组内的行编顺序,然后拼接成Member1、Member2这样的列名:old_dataframe['member_col'] = 'Member' + (old_dataframe.groupby('Reference_id').cumcount() + 1).astype(str)将长表转为宽表
用pivot函数把每个Reference_id对应的Name值展开到对应的Member列中:pivot_df = old_dataframe.pivot(index='Reference_id', columns='member_col', values='Name').reset_index()关联对应的Person_ID
观察你的目标结果,每个Reference_id对应的Person_ID是原始数据中Person_ID与Reference_id相等的那一行的值,我们先构建这个映射关系,再添加到透视后的表中:# 构建Reference_id到Person_ID的映射 ref_person_map = old_dataframe[old_dataframe['Person_ID'] == old_dataframe['Reference_id']].set_index('Reference_id')['Person_ID'].to_dict() pivot_df['Person_ID'] = pivot_df['Reference_id'].map(ref_person_map)调整列顺序并填充空值
把Person_ID移到最前面,同时把空值填充为空白(和你的示例格式一致):# 调整列顺序 pivot_df = pivot_df[['Person_ID', 'Reference_id', 'Member1', 'Member2', 'Member3']] # 填充空值为空白字符串 pivot_df = pivot_df.fillna('')
执行完这些步骤后,pivot_df就是你想要的目标DataFrame了!
为什么这个方案更好?
- 无需手动遍历:避免了循环带来的代码冗余和潜在错误,Pandas的向量化操作效率远高于手动循环,数据量越大优势越明显。
- 代码简洁可读:每一步都对应明确的逻辑,后续维护起来更方便。
- 扩展性强:如果后续需要支持更多Member列(比如Member4、Member5),只需要去掉列顺序中的硬编码,或者调整序号生成逻辑即可。
内容的提问来源于stack exchange,提问作者Stadelmann Kevin
相关产品推荐
相关产品推荐

