Python中DataFrame按site分组并将year转为列名的实现问题
解决方法
你的需求本质是将长格式DataFrame转换为宽格式,同时保留缺失年份的空值。原代码的问题在于分组时丢失了year与data的对应关系,导致无法正确映射年份列。以下是几种简洁的实现方式:
方法1:使用pivot(推荐,适用于无重复site+year组合的场景)
pivot是专门处理行列转换的函数,会自动匹配year作为列名,缺失的组合自动填充空值:
import pandas as pd # 构造原始DataFrame df = pd.DataFrame({ 'site': ['a', 'a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c'], 'year': [2010, 2011, 2012, 2013, 2010, 2012, 2013, 2010, 2011, 2012], 'data': [10, 12, 7, 45, 21, 45, 54, 17, 32, 24] }) # 转换为目标格式 result = df.pivot(index='site', columns='year', values='data').reset_index() result.columns.name = None # 移除列索引的名称(可选,让格式更贴近目标) print(result)
执行后输出:
| site | 2010 | 2011 | 2012 | 2013 |
|---|---|---|---|---|
| a | 10 | 12 | 7 | 45 |
| b | 21 | NaN | 45 | 54 |
| c | 17 | 32 | 24 | NaN |
方法2:使用groupby+unstack
如果需要更灵活的分组逻辑,可以先按site和year分组,再将year拆分为列:
result = df.groupby(['site', 'year'])['data'].first().unstack(fill_value=None) result = result.reset_index() result.columns.name = None
这里fill_value可以指定缺失值的填充内容(比如None或''),根据需求调整即可。
方法3:使用pivot_table(适用于存在重复site+year组合的场景)
如果你的数据中同一个site+year有多个data值,pivot_table可以通过aggfunc指定聚合方式(如求和、取均值):
result = pd.pivot_table( df, index='site', columns='year', values='data', aggfunc='first' # 若有重复值,可替换为'sum'/'mean'等 ).reset_index() result.columns.name = None
原代码问题说明
你之前的代码df.groupby('site')['data'].apply(lambda df: df.reset_index(drop=True)).unstack()只保留了每组data的顺序,丢失了year的对应信息,因此unstack后的列是0、1、2等序号,而非实际年份,自然无法处理缺失数据。
内容的提问来源于stack exchange,提问作者hanrahs
相关产品推荐
相关产品推荐

