基于时间序列在Pandas中构建月×年DataFrame的问题求助
解决方法:重塑时间序列数据为月份-年份矩阵
嘿,刚上手pandas遇到这种数据重塑问题太正常了!先给你说个最优解——完全不用写循环,pandas自带的pivot函数就能一键搞定,比迭代高效多了。不过先帮你找出之前循环代码的问题,再一步步讲最优方案。
先看你循环代码的问题
你的循环里有两个关键错误导致匹配失败:
output.items()用错了:这个方法返回的是DataFrame的(列名,列数据)元组,不是你要的月份名称列表。所以month变量是元组,和index.month_name()的字符串肯定匹配不上,自然触发不了后续赋值。- 没必要从DateTime提取月份:你的原数据已经有
Month列了,直接用row['Month']比从索引提取更可靠,避免格式不匹配的问题。
如果一定要用循环修复,代码可以改成这样:
# 假设你的output已经创建好,索引是月份名称(比如January到December),列是2004-2019的年份 # 先获取output的月份索引列表 target_months = output.index.tolist() for _, row in days.iterrows(): # 不需要index的话可以用_代替 current_month = row['Month'] current_year = row['Year'] current_days = row['Days'] # 检查当前月份是否在目标列表里 if current_month in target_months: # 用.at定位行和列赋值 output.at[current_month, current_year] = current_days
更优方案:用pandas的pivot函数(强烈推荐)
pandas专门提供了pivot/pivot_table来处理这种“长表转宽表”的需求,代码简洁且效率拉满,完全不用手动循环。步骤如下:
1. 确保月份顺序正确(可选但推荐)
默认pandas会按字母顺序排列月份,但我们想要自然顺序(January到December),可以把Month列转为分类类型并指定顺序:
import pandas as pd # 定义月份的自然顺序 month_order = [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] # 把原数据的Month列转为分类类型,指定顺序 days['Month'] = pd.Categorical(days['Month'], categories=month_order, ordered=True)
2. 一键生成目标DataFrame
用pivot函数直接重塑数据,指定行(index)是月份,列(columns)是年份,值(values)是Days:
# 生成目标矩阵 output = days.pivot(index='Month', columns='Year', values='Days') # 如果想把Month从索引转为普通列,执行下面这行 output = output.reset_index()
这样得到的output就是你想要的格式:行是按自然顺序排列的月份,列是年份,对应位置填充Days值,没有数据的地方自动显示NaN。
为什么推荐pivot?
- 代码简洁:一行代码搞定手动循环十几行的逻辑
- 效率更高:pandas内部用向量化操作处理,大数据量时比循环快几十倍
- 更少bug:避免手动循环时的索引、匹配错误
内容的提问来源于stack exchange,提问作者vicab
相关产品推荐
相关产品推荐

