如何选择合适的函数转换pandas DataSeries?长表转稀疏宽表需求
如何将Pandas长格式数据转换为稀疏宽格式?
嘿,这个需求其实是典型的长表转宽表场景,Pandas里有一套很顺手的操作能帮你搞定,我给你一步步拆解:
首先,核心思路是先给每个Time+Name分组内的行加上序号,这样我们才能生成Key1、Attr1这种带编号的列名,然后通过透视函数把多行转成多列。
步骤1:构造示例数据(还原你的输入)
先把你给的表格转成Pandas DataFrame:
import pandas as pd data = { 'Pseudo-id': [1, 2, 1, 3], 'Time': ['10:00', '10:00', '11:00', '11:00'], 'Name': ['A', 'A', 'B', 'B'], 'Key': ['Value', 'Value', 'Value', 'Value'], 'Attr': ['height', 'width', 'height', 'depth'], 'Value': [10, 20, 10, 20], 'Unit': ['mm', 'mm', 'mm', 'mm'] } df = pd.DataFrame(data)
步骤2:给分组内的行添加序号
我们需要给每个Time和Name组合下的行从1开始编号,这样后续才能区分不同的条目:
df['seq'] = df.groupby(['Time', 'Name']).cumcount() + 1
这一步会生成一个新列seq,比如10:00+A的两行,seq分别是1和2。
步骤3:透视转换为宽格式
用pivot函数把长表转成宽表,指定索引为Time和Name,列用刚才的seq,值就是你要展开的Key、Attr、Value、Unit:
pivoted = df.pivot(index=['Time', 'Name'], columns='seq', values=['Key', 'Attr', 'Value', 'Unit'])
步骤4:整理列名并重置索引
这时候的列名是多层的(比如('Key',1)),我们把它合并成你想要的Key1、Attr1格式,再把索引变回普通列:
# 合并多层列名 pivoted.columns = [f'{col[0]}{col[1]}' for col in pivoted.columns] # 重置索引,让Time和Name成为普通列 result = pivoted.reset_index()
最终结果
打印result就能得到你想要的稀疏格式:
| Time | Name | Key1 | Attr1 | Value1 | Unit1 | Key2 | Attr2 | Value2 | Unit2 |
|---|---|---|---|---|---|---|---|---|---|
| 10:00 | A | Value | height | 10 | mm | Value | width | 20 | mm |
| 11:00 | B | Value | height | 10 | mm | Value | depth | 20 | mm |
如果后续有更多行,它会自动生成Key3、Attr3这类列,完全适配你的稀疏格式需求。
另外如果你的数据里有重复的Time+Name+seq组合(比如同组同序号有两行),pivot会报错,这时候可以换成pivot_table,并指定aggfunc='first'(或者其他聚合方式)来处理重复值:
pivoted = df.pivot_table(index=['Time', 'Name'], columns='seq', values=['Key', 'Attr', 'Value', 'Unit'], aggfunc='first')
内容的提问来源于stack exchange,提问作者Laokoon
相关产品推荐
相关产品推荐

