在数字化理财的时代,清晰的消费分析能帮助我们洞察支出结构、优化财务规划。本文将介绍如何开发一个个人月度消费分析工具,它能读取CSV格式的消费记录,自动统计各类支出的总金额、日均支出,并通过可视化图表直观展示消费结构(饼图)和每日支出趋势(折线图)。这个工具不仅能提升个人理财效率,还能帮助开发者巩固文件处理、数据统计、可视化等核心技能。
一、实现思路分析
要完成这个工具,我们将分四步走:
1. 文件读取与预处理
使用 pandas 读取CSV文件,自动解析日期列(parse_dates),处理空值和非数值金额,确保数据格式正确。
2. 数据统计
- 按类别统计:分组计算每类消费的总支出、消费次数,并结合日期范围计算日均支出。
- 按日期统计:分组计算每日总支出,为折线图提供数据。
3. 可视化展示
- 饼图:展示各消费类别占总支出的比例,自定义颜色、标签和百分比格式。
- 折线图:展示每日总支出的变化趋势,优化x轴日期显示(如“月-日”格式)。
4. 异常处理
通过 try-except 捕获文件读取和数据处理中的错误,跳过无效行(如日期格式错误、金额为空)。
二、代码实现(Python)
以下是完整的代码实现,包含详细注释:
import pandas as pd
import matplotlib.pyplot as plt
import os
def read_expense_data(file_path):
"""读取并预处理CSV格式的消费数据"""
try:
# 读取CSV,自动解析日期列,处理空值
df = pd.read_csv(
file_path,
parse_dates=['日期'], # 自动识别日期格式
na_values=['nan', 'NaN', ''] # 标记空值
)
# 过滤金额为空或非数值的行
df = df.dropna(subset=['金额']) # 移除金额为空的行
df['金额'] = df['金额'].astype(float) # 转换金额为浮点数
df = df.sort_values(by='日期') # 按日期排序
return df
except Exception as e:
print(f"文件读取/处理出错:{e}")
return None
def analyze_by_category(df):
"""按消费类别统计:总支出、消费次数、日均支出"""
# 按类别分组,聚合计算总支出和消费次数
category_stats = df.groupby('类别').agg(
总支出=('金额', 'sum'),
消费次数=('金额', 'count')
).reset_index() # 重置索引,使类别作为列
# 计算日期范围的天数(包含首尾两天)
min_date = df['日期'].min()
max_date = df['日期'].max()
days = (max_date - min_date).days + 1 # 总天数 = 结束日-开始日 + 1
# 计算日均支出(总支出 ÷ 总天数)
category_stats['日均支出'] = category_stats['总支出'] / days
return category_stats, min_date, max_date, days
def analyze_by_day(df):
"""按日期统计每日总支出"""
daily_stats = df.groupby('日期').agg(
每日总支出=('金额', 'sum')
).reset_index()
return daily_stats
def plot_category_pie(category_stats, output_path='category_pie.png'):
"""绘制消费类别占比饼图"""
# 设置中文字体,避免乱码
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
# 提取数据
categories = category_stats['类别'].tolist()
totals = category_stats['总支出'].tolist()
total_expense = sum(totals) # 总支出(用于百分比计算)
# 绘制饼图
fig, ax = plt.subplots(figsize=(8, 6))
wedges, texts, autotexts = ax.pie(
totals,
labels=categories,
autopct='%1.2f%%', # 百分比格式(保留2位小数)
startangle=90, # 起始角度(使饼图顶部为第一个类别)
colors=['#ff9999', '#66b3ff', '#99ff99', '#ffcc99'] # 自定义颜色
)
# 美化文本(标签和百分比)
for text in texts + autotexts:
text.set_fontsize(12)
ax.set_title('消费类别占比', fontsize=16)
ax.axis('equal') # 保证饼图为圆形
plt.tight_layout() # 自动调整布局
plt.savefig(output_path) # 保存图表
plt.close()
print(f"饼图已保存至:{output_path}")
def plot_daily_trend(daily_stats, output_path='daily_trend.png'):
"""绘制每日消费趋势折线图"""
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
# 提取日期(格式化为“月-日”)和每日总支出
dates = daily_stats['日期'].dt.strftime('%m-%d') # 转换为字符串格式
daily_totals = daily_stats['每日总支出'].tolist()
# 绘制折线图
fig, ax = plt.subplots(figsize=(10, 6))
ax.plot(
dates,
daily_totals,
marker='o', # 数据点标记
linestyle='-', # 折线样式
color='#66b3ff' # 折线颜色
)
# 设置图表标签与标题
ax.set_xlabel('日期', fontsize=12)
ax.set_ylabel('总支出(元)', fontsize=12)
ax.set_title('每日消费趋势', fontsize=16)
plt.xticks(rotation=45, ha='right') # 旋转x轴标签,避免重叠
plt.tight_layout()
plt.savefig(output_path)
plt.close()
print(f"折线图已保存至:{output_path}")
def main():
"""主函数:整合数据读取、统计、可视化流程"""
# 输入文件路径
file_path = input("请输入CSV消费记录文件路径(如expenses.csv):")
if not os.path.exists(file_path):
print(f"错误:文件不存在 → {file_path}")
return
# 1. 读取数据
df = read_expense_data(file_path)
if df is None or df.empty:
print("数据为空或读取失败,程序终止。")
return
# 2. 按类别统计
category_stats, min_date, max_date, days = analyze_by_category(df)
# 3. 按日期统计
daily_stats = analyze_by_day(df)
# 4. 计算总支出
total_expense = category_stats['总支出'].sum()
# 打印统计结果
print(f"\n===== 消费统计({min_date.strftime('%Y-%m-%d')} ~ {max_date.strftime('%Y-%m-%d')}) =====")
for _, row in category_stats.iterrows():
print(f"- {row['类别']}:总支出 {row['总支出']:.2f} 元,日均 {row['日均支出']:.2f} 元(共{days}天,消费{row['消费次数']}次)")
print(f"总支出:{total_expense:.2f} 元,日均 {total_expense/days:.2f} 元\n")
# 5. 可视化
plot_category_pie(category_stats)
plot_daily_trend(daily_stats)
print("分析完成!")
if __name__ == "__main__":
main()
三、代码运行与测试
1. 准备CSV文件
创建 expenses.csv,内容如下(示例数据):
日期,类别,金额
2023-10-01,餐饮,50.0
2023-10-01,购物,100.0
2023-10-02,交通,10.0
2023-10-02,餐饮,30.0
2023-10-03,购物,50.0
2. 安装依赖
确保已安装 pandas 和 matplotlib:
pip install pandas matplotlib
3. 运行程序
执行脚本后,输入CSV文件路径(如 expenses.csv),程序会自动输出统计结果并生成两张图表(category_pie.png 和 daily_trend.png)。
四、扩展与优化方向
- 多文件合并:支持读取多个CSV文件,合并后分析更长周期的消费数据。
- 交互界面:使用
Streamlit或Tkinter开发图形界面,提升用户体验。 - 自动导入:对接银行/支付平台API,自动拉取消费数据,减少手动录入成本。
- 高级分析:添加支出预警(如超预算提醒)、消费模式识别(如周期性支出分析)。
总结
通过这个项目,我们实践了数据处理→统计分析→可视化的完整流程,掌握了:
– pandas 高效处理CSV、日期解析、分组统计的技巧。
– matplotlib 绘制专业可视化图表的方法(饼图、折线图)。
– 异常处理与鲁棒性设计,确保工具在复杂场景下稳定运行。
这个工具不仅能帮助个人管理财务,更能作为开发者巩固核心技能的实践项目。如果你有更多需求,不妨基于此代码进行扩展,让它更贴合你的理财习惯!