背景介绍
在个人理财中,清晰的支出统计与趋势分析能帮助我们更好地管理财务。本文将介绍如何使用Python开发一个“个人支出分析工具”,通过解析CSV格式的支出记录,完成数据统计与可视化,让支出情况一目了然。该工具适合Python初学者学习数据处理(pandas)、可视化(matplotlib)与GUI交互(Tkinter)的结合应用。
思路分析
工具的核心流程分为四步:
1. 数据解析:读取CSV文件,转换日期为“年月”格式、金额为数值类型。
2. 统计分析:
– 按“类别”分组:统计总金额、平均金额、交易次数。
– 按“年月”分组:统计月度总支出。
3. 可视化展示:
– 柱状图:对比不同类别总支出。
– 折线图:展示月度支出趋势。
4. 用户交互:通过Tkinter的文件选择对话框,让用户选择CSV文件,简化操作。
代码实现
1. 导入依赖库
我们需要pandas处理数据、matplotlib绘图、Tkinter实现文件选择:
import pandas as pd
import matplotlib.pyplot as plt
from tkinter import Tk, filedialog
2. 数据解析函数
读取CSV文件,处理日期和金额格式:
def load_and_process_data(file_path):
"""读取CSV文件并处理日期、金额格式"""
# 读取CSV(假设列名包含“日期”“类别”“金额”)
df = pd.read_csv(file_path)
# 日期转换:提取“年月”格式(如2023-01)
df['日期'] = pd.to_datetime(df['日期'])
df['年月'] = df['日期'].dt.strftime('%Y-%m')
# 金额转换:确保为数值类型
df['金额'] = df['金额'].astype(float)
return df
3. 统计分析函数
按类别和年月分别统计支出数据:
def category_stats(df):
"""按类别分组统计:总金额、平均金额、交易次数"""
# groupby+agg聚合计算(sum=总金额, mean=平均金额, count=交易次数)
stats = df.groupby('类别')['金额'].agg(['sum', 'mean', 'count']).reset_index()
# 重命名列名,方便后续使用
stats.columns = ['类别', '总金额', '平均金额', '交易次数']
return stats
def monthly_stats(df):
"""按年月分组统计月度总支出"""
monthly = df.groupby('年月')['金额'].sum().reset_index()
return monthly
4. 可视化函数
用matplotlib绘制类别柱状图和月度折线图:
def plot_category_bar(stats, title='类别支出统计', colors=None):
"""绘制类别支出柱状图(带数值标注)"""
if colors is None:
colors = ['red', 'blue', 'green'] # 默认颜色方案
plt.figure(figsize=(8, 6)) # 设置图表大小
bars = plt.bar(stats['类别'], stats['总金额'], color=colors)
plt.title(title, fontsize=14)
plt.xlabel('支出类别', fontsize=12)
plt.ylabel('总金额(元)', fontsize=12)
# 在柱子上标注数值(避免和顶部重叠,+0.5偏移)
for bar in bars:
height = bar.get_height()
plt.text(
bar.get_x() + bar.get_width() / 2, # 水平居中
height + 0.5, # 垂直位置
f'{height:.1f}',
ha='center', va='bottom'
)
plt.tight_layout() # 自动调整布局,避免标签截断
return plt.gcf() # 返回图表对象,方便保存
def plot_monthly_line(monthly, title='月度支出趋势', line_color='black', marker='o'):
"""绘制月度支出折线图(按时间排序)"""
# 按年月升序排序(确保X轴时间顺序正确)
monthly = monthly.sort_values('年月')
plt.figure(figsize=(8, 6))
plt.plot(
monthly['年月'],
monthly['金额'],
color=line_color,
marker=marker,
linestyle='-',
markersize=6
)
plt.title(title, fontsize=14)
plt.xlabel('年月', fontsize=12)
plt.ylabel('总支出(元)', fontsize=12)
plt.xticks(rotation=45) # X轴标签旋转45度,避免重叠
plt.tight_layout()
return plt.gcf()
5. 用户交互与主函数
通过Tkinter选择CSV文件,整合数据解析→统计→可视化流程:
def main():
# 初始化Tkinter(隐藏主窗口,只显示文件选择框)
root = Tk()
root.withdraw()
# 打开文件选择对话框
file_path = filedialog.askopenfilename(
title='选择支出CSV文件',
filetypes=[('CSV Files', '*.csv')]
)
if not file_path:
print('未选择文件,程序退出。')
return
# 1. 数据解析
df = load_and_process_data(file_path)
# 2. 统计分析
cat_stats = category_stats(df)
monthly = monthly_stats(df)
# 3. 输出文本统计结果
print('=== 类别支出统计 ===')
for _, row in cat_stats.iterrows():
print(f"{row['类别']}:总金额{row['总金额']:.1f}元,平均{row['平均金额']:.1f}元,交易{row['交易次数']}次")
print('\n=== 月度支出统计 ===')
for _, row in monthly.iterrows():
print(f"{row['年月']}:总支出{row['金额']:.1f}元")
# 4. 可视化并保存图表
# 类别柱状图(保存为PNG)
cat_fig = plot_category_bar(cat_stats, title='类别支出对比')
cat_fig.savefig('category_expenses.png')
# 月度折线图(保存为PNG)
monthly_fig = plot_monthly_line(monthly, title='月度支出趋势')
monthly_fig.savefig('monthly_expenses.png')
print('\n统计完成!图表已保存为:')
print('- 类别支出柱状图:category_expenses.png')
print('- 月度支出折线图:monthly_expenses.png')
if __name__ == '__main__':
main()
运行与测试
- 环境准备:安装依赖库
pip install pandas matplotlib - 测试数据:使用包含
日期、类别、金额字段的CSV文件(示例数据见问题描述)。 -
运行程序:执行脚本后,通过Tkinter选择CSV文件,程序会输出统计文本并生成两张图表。
总结
本工具通过pandas高效处理CSV数据,matplotlib实现直观可视化,Tkinter简化用户交互,完整覆盖了数据解析→统计分析→可视化的流程。通过这个项目,我们学习了:
– pandas的groupby与agg聚合操作,高效处理分组统计。
– matplotlib的图表定制(颜色、标签、数值标注),提升可视化效果。
– Tkinter的文件选择交互,增强程序的易用性。
对于进阶优化,可扩展功能如多文件合并分析、支出预算对比、饼图展示类别占比等。快用自己的支出数据试试,看看钱都花去哪儿了吧!
(代码可直接复制运行,需确保CSV文件字段与代码逻辑匹配。)