You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何用Pandas绘制3年周期内36个月份的企业营收趋势图

解决按自然月份(含年份)展示36个月营收趋势的问题

我明白你的问题了——原来的分组逻辑只按月份数字聚合,会把2016年10月、2017年10月、2018年10月的营收合并到一起,自然只能看到12个汇总结果,丢失了年份维度,没法呈现完整的36个月趋势。下面是具体的修正方案:

核心思路

要保留每个自然月的独立性,必须同时按年份+月份分组,或者直接用Pandas的dt.to_period('M')方法提取「年月周期」作为分组键,这样每个YYYY-MM都是唯一的分组单元,不会跨年份合并。


步骤1:预处理数据(确保日期格式正确)

首先确认你的Datetime列是Pandas的datetime类型,如果不是先转换:

import pandas as pd
import matplotlib.pyplot as plt

# 转换日期列(如果原始数据是字符串格式)
df['Datetime'] = pd.to_datetime(df['Datetime'])

步骤2:按年月周期分组汇总

dt.to_period('M')直接生成「年月」分组键,这是最简洁的方式:

# 按公司+年月周期分组,计算每月总营收
monthly_sums = df.groupby(
    ['Company Name', df['Datetime'].dt.to_period('M')]
)['PaidTotal'].sum().reset_index(name='MonthlyTotal')

# 将周期类型转为字符串(方便绘图时显示)
monthly_sums['Year-Month'] = monthly_sums['Datetime'].astype(str)

这个操作会把每一行的日期转为对应的YYYY-MM格式(比如2016-10-14变成2016-10),每个自然月都会作为独立的分组,不会和其他年份的同月合并。

步骤3:绘制36个月趋势图

确保每个公司的数据按时间排序后再绘图,这样趋势是连续的:

# 创建画布
fig, ax = plt.subplots(figsize=(12, 6))

# 遍历每个公司绘制趋势线
for company in monthly_sums['Company Name'].unique():
    # 筛选当前公司数据并按时间排序
    company_data = monthly_sums[monthly_sums['Company Name'] == company].sort_values('Datetime')
    # 绘制折线图
    company_data.plot(
        x='Year-Month', 
        y='MonthlyTotal', 
        label=company, 
        ax=ax,
        marker='o'  # 添加标记点更清晰
    )

# 美化图表
plt.title('3-Year Monthly Revenue Trend by Company')
plt.xlabel('Year-Month')
plt.ylabel('Total Paid Revenue')
plt.xticks(rotation=45, ha='right')  # 旋转x轴标签避免重叠
plt.legend(title='Company')
plt.tight_layout()
plt.show()

额外优化:补全缺失月份(可选)

如果你的数据中有某个公司某月份没有营收记录(比如示例中CompanyA 2016年11月没有数据),上面的结果会跳过该月份。如果需要展示连续的36个月(缺失月份填0),可以用pivot_table生成宽表:

# 生成宽表,缺失值填充0
pivot_df = monthly_sums.pivot(
    index='Datetime',
    columns='Company Name',
    values='MonthlyTotal'
).fillna(0).astype(int)

# 直接绘制连续趋势
pivot_df.plot(figsize=(12,6), marker='o')
plt.title('Continuous 3-Year Monthly Revenue Trend')
plt.xlabel('Year-Month')
plt.ylabel('Total Paid Revenue')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()

灵活扩展:任意月份周期

如果想要查看特定时间范围的趋势(比如2017-01到2018-12的24个月),只需先筛选数据再分组:

# 筛选目标时间范围
mask = (df['Datetime'] >= '2017-01-01') & (df['Datetime'] <= '2018-12-31')
filtered_df = df[mask]

# 后续分组和绘图逻辑和上面一致
monthly_sums_filtered = filtered_df.groupby(
    ['Company Name', filtered_df['Datetime'].dt.to_period('M')]
)['PaidTotal'].sum().reset_index(name='MonthlyTotal')

内容的提问来源于stack exchange,提问作者Azm

火山引擎 最新活动