看过来
《pandas 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gr99123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
把“日期”列拆成年/月/周,再按“类别”做行→列透视,是日报、月报里最常遇到的“重复性体力劳动”。 今天用 2 个低调却高频的 pandas 方法——pd.to_datetime
与 pivot_table
——一条链式代码完成“拆日期+透视+排序+重命名”全家桶,让你 5 分钟交差,还能早 1 小时下班摸鱼。
原始数据如下:
import pandas as pd
from io import StringIO
raw = """日期,类别,销量
2024-06-01,手机,120
2024-06-01,配件,80
2024-06-02,手机,150
2024-06-02,配件,90
2024-06-08,手机,200
2024-06-09,配件,110
2024-07-01,手机,180
2024-07-02,配件,95"""
df = pd.read_csv(StringIO(raw))
df
'''
日期 类别 销量
0 2024-06-01 手机 120
1 2024-06-01 配件 80
2 2024-06-02 手机 150
3 2024-06-02 配件 90
4 2024-06-08 手机 200
5 2024-06-09 配件 110
6 2024-07-01 手机 180
7 2024-07-02 配件 95
'''
需求描述:
正确结果示意:
手机 配件
年 月 周
2024 6 22 270 170
23 200 110
7 27 180 95
我们的大体思路如下:
① pd.to_datetime
把字符串转日期 → ② .dt.isocalendar()
一次拿到年/月/周 → ③ pivot_table
透视,索引=年+月+周,列=类别,值=sum(销量) → ④ 调换列顺序、重置索引名称,一条链到底。
参考链式代码如下:
(
df
.assign(日期=pd.to_datetime(df['日期'])) # ① 转日期类型
.assign(年=lambda x: x['日期'].dt.year, # ② 拆出年/月/周
月=lambda x: x['日期'].dt.month,
周=lambda x: x['日期'].dt.isocalendar().week)
.pivot_table(index=['年', '月', '周'], # ③ 透视
columns='类别',
values='销量',
aggfunc='sum',
fill_value=0)
.reindex(columns=['手机', '配件']) # ④ 列顺序
.rename_axis(columns=None) # 干掉顶部“类别”
.sort_index() # 时间升序
)
'''
手机 配件
年 月 周
2024 6 22 270 170
23 200 110
7 27 180 95
'''
代码拆解
assign
三连击:一次性追加三列,避免多次 df[] =
破坏链式风格。dt.isocalendar().week
直接返回 ISO 周数,比手动算 //7
更准。pivot_table
默认 margins=False
,干净清爽;fill_value=0
让空周显示 0 而不是 NaN。reindex(columns=[...])
保证“手机”永远在左,老板看图不扭头。学会“日期→年/月/周”+“透视”这两个高频套路,日报、周报、月报都能 1 行代码交差。 下回再被催“快点出透视表”,直接把本文链式代码甩过去,让同事感受 pandas 的暴力美学。
(完)
更新时间:2025-09-07 15:05:05 标签:pandas python 透视