如何按ID和时间透视含混合值类型的Pandas DataFrame
解决Pandas长表转宽表的问题
刚好碰到过类似的需求,用Pandas的pivot()或者pivot_table()就能完美解决你这种把Category转成单独列的需求,给你一步步拆解下:
1. 先构造示例DataFrame(方便你复现测试)
首先把你给出的示例数据转成可运行的代码:
import pandas as pd data = { 'ID': [457, 542, 542, 542, 457, 457], 'Time': ['2010-09-04 15:00', '2010-09-04 15:00', '2010-09-04 15:00', '2010-09-04 15:00', '2010-09-04 15:40', '2010-09-04 15:40'], 'Category': ['Name', 'Name', 'Sub', 'Age', 'Sub', 'Age'], 'Value': ['Foo', 'Bar', 0.2, 18, 0.7, 20] } df = pd.DataFrame(data)
2. 核心转换代码(无重复值场景)
如果你的数据里同一个ID+Time+Category组合没有重复值,用pivot()是最高效的:
# 转成宽表 cat_df = df.pivot( index=['ID', 'Time'], # 作为行唯一标识的组合键 columns='Category', # 要转成列的字段 values='Value' # 对应列的取值 ).reset_index() # 去掉列名的层级标记,让表格更整洁 cat_df.columns.name = None
3. 处理重复值场景
如果存在同一个ID+Time+Category有多条记录的情况,pivot()会报错,这时候用pivot_table()搭配聚合函数更稳妥:
# 用first取第一个值,你也可以根据需求换成mean/sum等聚合逻辑 cat_df = df.pivot_table( index=['ID', 'Time'], columns='Category', values='Value', aggfunc='first' ).reset_index() cat_df.columns.name = None
4. 转换后的结果
最终的cat_df结构如下:
| ID | Time | Age | Name | Sub |
|---|---|---|---|---|
| 457 | 2010-09-04 15:00 | NaN | Foo | NaN |
| 457 | 2010-09-04 15:40 | 20 | NaN | 0.7 |
| 542 | 2010-09-04 15:00 | 18 | Bar | 0.2 |
5. 可选:填充空值
如果想把结果里的NaN换成你需要的默认值,比如空字符串或0,可以用fillna():
# 全部填充为空字符串 cat_df = cat_df.fillna('') # 或者针对数值列单独填充0 cat_df[['Age', 'Sub']] = cat_df[['Age', 'Sub']].fillna(0)
内容的提问来源于stack exchange,提问作者HMK
相关产品推荐
相关产品推荐

