尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

Python数据分析实战:个人记账数据处理与可视化全流程

Python数据分析实战:个人记账数据处理与可视化全流程 简介数据分析作为从海量信息中提取价值、指导决策的核心技术其基础在于对结构化数据的有效处理与洞察。在Python生态中Pandas凭借其强大的DataFrame数据结构和向量化计算能力成为数据清洗、转换和聚合的事实标准工具而Matplotlib与Seaborn则构成了静态可视化的基石能将抽象数据转化为直观图表。这套技术组合的工程价值在于它将重复、琐碎的手工分析自动化、标准化显著提升了从原始数据到业务洞察的效率。在个人财务管理这一典型应用场景中面对零散的支付账单和流水记录通过Pandas进行数据加载、清洗、分类与聚合再结合Matplotlib/Seaborn绘制消费结构饼图、趋势折线图和预算对比柱状图便能构建一个自动化的消费洞察系统。本文即围绕这一主题详细拆解了如何利用这些工具将多来源的记账数据转化为清晰的可视化图表并实现消费行为的自动化分析从而精准定位财务流向赋能个人财务决策。1. 项目概述从零散账本到消费洞察每次月底看着手机里十几个支付APP的账单或者Excel里记了又忘的流水是不是总有种“钱不知道花哪儿了”的无力感我自己就这么过了好几年直到开始用Python处理自己的记账数据才真正把一团乱麻的消费变成了清晰的行动指南。这个项目就是把我这套从数据清洗、分析到可视化的完整流程打包成一个你可以直接上手运行的Python源码示例。它不是什么高深的企业级系统目标非常单纯把你日常那些零散的记账数据不管是导出的Excel、CSV还是手动记录的文本通过几行代码变成一眼就能看懂的可视化图表从而精准定位你的消费黑洞理清个人财务流向。你会发现核心工具就是Python里那几个数据分析的“老伙计”Pandas负责像瑞士军刀一样处理表格数据Matplotlib和Seaborn用来绘制直观的图表。整个过程就像做菜数据是原料这些库是厨具而我们的分析思路就是菜谱。这个源码包的价值在于它提供了一套经过实战检验的“菜谱”和“预处理流程”你不需要从零开始研究每个函数怎么用而是可以快速套用自己的数据看到立竿见影的分析结果。无论是想了解每月餐饮开销占比、网购的波动趋势还是对比投资与消费的平衡这个工具都能给你提供数据上的支撑。2. 核心分析思路与框架设计2.1 需求拆解我们到底要分析什么在动手写代码之前明确目标至关重要。个人记账数据分析通常逃不开下面几个核心问题这也是我们代码框架设计的出发点消费结构分析钱花在哪儿了这是最基础的需求。我们需要将支出按类别如餐饮、交通、购物、学习、娱乐聚合计算每个类别的总金额和占比。这里的关键在于“分类”原始数据往往只有一条条流水需要有一套规则或映射表将其归类。消费趋势分析钱是怎么花的观察消费随时间的变化。是每月平稳还是有大起大落发工资后是否有一波消费高峰这需要按时间月、周进行聚合统计生成折线图或柱状图。收入-支出平衡分析钱够不够花这是财务健康的核心。计算每月净收入收入-支出观察储蓄率。理想情况下我们希望看到一条稳步上升的净资产曲线。异常消费识别钱花得冤不冤找出那些单笔金额过高、或不符合日常习惯的消费。比如平时餐饮日均50元突然出现一笔500元的记录就需要标记出来回顾。预算与实际对比计划与现实的差距如果你有预算那么将实际消费与预算对比能直观看到哪些类别超支为下个月调整提供依据。基于这些需求我们的代码框架自然分成了几个模块数据加载与清洗 - 分类与结构化 - 多维度聚合计算 - 可视化图表输出。2.2 工具选型为什么是Pandas Matplotlib/Seaborn市面上数据分析工具很多为什么选择这个组合Pandas它是Python数据分析的事实标准。对于表格型数据我们的记账流水本质就是一张有日期、分类、金额、备注的表格Pandas的DataFrame数据结构操作起来无比顺手。其强大的数据清洗处理空值、重复值、分组聚合groupby、时间序列处理功能完美契合我们的所有需求。相比直接操作Excel用代码处理可重复、可追溯、能处理更大量级的数据。Matplotlib这是Python绘图的基石库功能强大且灵活几乎能绘制任何你想要的2D图表。我们用它来绘制折线图趋势、柱状图对比、饼图占比等基础图表。虽然其默认样式比较朴素但通过调整参数完全可以做出出版级的图表。Seaborn它基于Matplotlib提供了更高级的API和更美观的默认样式。特别是在绘制统计关系图如分布图、箱线图时Seaborn往往一两行代码就能实现Matplotlib多行的效果。在我们的项目中可以用它快速绘制消费金额的分布情况看看自己的消费是集中在小额还是分散。这个组合的另一个巨大优势是生态和社区。无论遇到什么问题几乎都能找到丰富的解决方案和案例参考学习成本相对较低。注意有些朋友可能会想到用Plotly或Pyecharts做交互式图表。它们确实酷炫但对于个人定期复盘这种“生产-查看”的场景静态图表导出为PNG或PDF更简单、更稳定也更容易嵌入到文档或笔记中。我们的源码以静态分析为核心保证通用性和易用性。2.3 数据准备你的记账数据从哪来巧妇难为无米之炊。在运行代码前你需要把自己的流水整理成程序能读的格式。通常有两种路径导出标准文件这是最推荐的方式。几乎所有银行APP、支付工具微信、支付宝都支持将账单导出为CSV或Excel格式。你只需要定期如每月一次将这些文件下载到本地同一个文件夹。我们的代码可以编写一个循环自动读取该文件夹下所有文件并合并。手动维护表格如果你有自己记流水账的习惯可以手动维护一个Excel或CSV文件。建议固定列名例如日期、类型收入/支出、金额、一级分类、二级分类、支付方式、备注。结构越规范后续分析越轻松。我个人的做法是每月初花10分钟从支付宝、微信、信用卡APP分别导出上月账单CSV格式存到一个固定目录。然后运行我的Python脚本一切就自动生成了。3. 数据处理核心步骤详解3.1 数据加载与初步清洗拿到原始数据后第一步不是马上分析而是“搞卫生”。原始导出数据常常包含表头、汇总行、无效列等“垃圾信息”。import pandas as pd import glob # 1. 读取单个或多个数据文件 # 假设你的账单CSV文件都放在 ./data/ 目录下 file_paths glob.glob(./data/*.csv) # 获取所有csv文件路径 df_list [] for file in file_paths: # 读取时可能需指定编码跳过无关行 temp_df pd.read_csv(file, encodinggbk, skiprows1) # 例如支付宝导出文件可能需要跳过首行说明 df_list.append(temp_df) # 合并所有数据 raw_df pd.concat(df_list, ignore_indexTrue) # 2. 查看数据概览做到心中有数 print(f“数据总行数 {raw_df.shape[0]}”) print(“数据前5行”) print(raw_df.head()) print(“\n列信息”) print(raw_df.columns) print(“\n基本统计信息”) print(raw_df.describe())这个阶段的关键是了解你的数据有哪些列列名是什么金额列是字符串还是数字日期格式对吗通过head(),columns,info()这几个函数你能快速摸清情况。3.2 关键字段提取与标准化导出数据的列名往往是中文且不统一比如“交易时间”、“收/支”、“金额(元)”。我们需要将其标准化为程序友好的英文或简单中文列名并统一格式。# 3. 列名重命名根据你的实际文件列名调整 # 这是一个映射示例你需要根据自己导出文件的表头修改 column_mapping { ‘交易时间’: ‘date’, ‘收/支’: ‘type’, ‘金额(元)’: ‘amount’, ‘交易对方’: ‘counterparty’, ‘商品说明’: ‘description’ } df raw_df.rename(columnscolumn_mapping) # 4. 类型转换与清洗 # 确保日期是日期类型 df[‘date’] pd.to_datetime(df[‘date’], errors‘coerce’) # errors‘coerce’将解析错误的日期转为NaT # 确保金额是数值类型需去除货币符号和逗号 df[‘amount’] df[‘amount’].astype(str).str.replace(‘¥’, ‘’).str.replace(‘,’, ‘’).astype(float) # 处理收支类型统一为‘收入’和‘支出’ df[‘type’] df[‘type’].map({‘收入’: ‘income’, ‘支出’: ‘expense’, ‘支’: ‘expense’, ‘收’: ‘income’}) # 5. 处理缺失值和异常值 # 删除日期或金额为空的关键行 df_clean df.dropna(subset[‘date’, ‘amount’, ‘type’]) # 过滤掉金额为0或异常大的记录根据实际情况设定阈值 df_clean df_clean[(df_clean[‘amount’] ! 0) (df_clean[‘amount’].abs() 1000000)]实操心得pd.to_datetime的errors‘coerce’参数非常有用它能把所有格式不对的日期比如一些备注文字混了进去变成空值NaT而不是让整个程序报错中断方便我们后续统一清理。3.3 消费分类的自动化与映射这是整个分析中最具个性化也最核心的一步。我们需要根据交易的“对方名称”或“商品说明”自动将其归入预设的消费类别如“餐饮”、“交通”。最实用的方法是建立一个分类关键词映射字典。# 6. 基于描述的关键词分类 def categorize_transaction(description, counterparty): “”“根据描述和对方名称判断消费类别”“” desc_str str(description).lower() cp_str str(counterparty).lower() # 定义分类规则字典 category_rules { ‘餐饮’: [‘餐厅’, ‘饭店’, ‘快餐’, ‘奶茶’, ‘咖啡’, ‘美团’, ‘饿了么’, ‘星巴克’], ‘交通’: [‘滴滴’, ‘地铁’, ‘公交’, ‘加油’, ‘停车’, ‘高德’, ‘打车’, ‘通行费’], ‘购物’: [‘淘宝’, ‘京东’, ‘拼多多’, ‘超市’, ‘百货’, ‘服饰’, ‘鞋’, ‘数码’], ‘生活缴费’: [‘水费’, ‘电费’, ‘燃气费’, ‘话费’, ‘网费’, ‘物业’], ‘学习’: [‘书籍’, ‘课程’, ‘培训’, ‘会员’], ‘娱乐’: [‘电影’, ‘游戏’, ‘旅游’, ‘门票’, ‘视频会员’], ‘医疗’: [‘医院’, ‘药店’, ‘诊所’, ‘医保’], ‘投资理财’: [‘基金’, ‘股票’, ‘理财’, ‘定投’], ‘收入’: [‘工资’, ‘奖金’, ‘转账收入’, ‘理财收益’] } for category, keywords in category_rules.items(): for kw in keywords: if kw in desc_str or kw in cp_str: return category return ‘其他’ # 未匹配到的归为其他 # 应用分类函数 df_clean[‘category’] df_clean.apply(lambda row: categorize_transaction(row[‘description’], row[‘counterparty’]), axis1) # 对于‘收入’类型类别直接标记为‘收入’ df_clean.loc[df_clean[‘type’] ‘income’, ‘category’] ‘收入’这个方法的优点是灵活、可维护。当你发现某笔消费分类错了只需要在category_rules字典里增删关键词即可。初期可能需要手动校正一些记录但随着规则完善自动化程度会越来越高。4. 多维数据分析与可视化实现数据清洗分类完成后就进入了有趣的“挖宝”阶段。我们通过不同的维度切片来回答最初提出的那些问题。4.1 消费结构分析你的钱流向了哪里这是通过饼图或环形图来直观展示消费构成。import matplotlib.pyplot as plt # 筛选支出数据 expense_df df_clean[df_clean[‘type’] ‘expense’] # 按类别聚合支出金额 category_expense expense_df.groupby(‘category’)[‘amount’].sum().abs().sort_values(ascendingFalse) # 绘制饼图 plt.figure(figsize(10, 8)) # autopct显示百分比 startangle设置起始角度 plt.pie(category_expense.values, labelscategory_expense.index, autopct‘%1.1f%%’, startangle90) plt.axis(‘equal’) # 保证饼图是圆形 plt.title(‘月度消费结构分析’) plt.show() # 更优选择绘制环形图中间可以放总计 plt.figure(figsize(10,8)) wedges, texts, autotexts plt.pie(category_expense.values, labelscategory_expense.index, autopct‘%1.1f%%’, startangle90) # 画一个白色的圆在中间变成环形图 centre_circle plt.Circle((0,0),0.70,fc‘white’) fig plt.gcf() fig.gca().add_artist(centre_circle) plt.title(‘月度消费结构分析环形图’) plt.show()注意事项饼图类别不宜过多通常展示前6-8个主要类别将剩余小类别合并为“其他”。否则切片太多图表会显得杂乱。我们的代码中通过.sort_values(ascendingFalse)已经按金额从大到小排序可以在绘图前只取前N项。4.2 消费趋势分析时间线上的消费习惯我们使用折线图来观察支出随时间按天或按周的变化使用柱状图来对比不同月份的消费总额。# 按月份聚合支出与收入 df_clean[‘month’] df_clean[‘date’].dt.to_period(‘M’) # 提取年月周期 monthly_summary df_clean.groupby([‘month’, ‘type’])[‘amount’].sum().unstack(fill_value0) monthly_summary[‘expense’] monthly_summary.get(‘expense’, 0).abs() # 支出取绝对值 monthly_summary[‘income’] monthly_summary.get(‘income’, 0) monthly_summary[‘savings’] monthly_summary[‘income’] - monthly_summary[‘expense’] # 计算每月结余 # 绘制多子图趋势 fig, axes plt.subplots(2, 1, figsize(14, 10)) # 子图1月度收入与支出柱状图 x monthly_summary.index.astype(str) width 0.35 axes[0].bar(x, monthly_summary[‘income’], width, label‘收入’, color‘lightgreen’) axes[0].bar(x, monthly_summary[‘expense’], width, label‘支出’, bottommonthly_summary[‘income’], color‘lightcoral’) axes[0].set_ylabel(‘金额 (元)’) axes[0].set_title(‘月度收入与支出对比’) axes[0].legend() axes[0].tick_params(axis‘x’, rotation45) # 子图2月度结余储蓄折线图 axes[1].plot(x, monthly_summary[‘savings’], marker‘o’, linestyle‘-’, color‘blue’, linewidth2) axes[1].axhline(y0, color‘red’, linestyle‘—’, linewidth0.8) # 添加0基准线 axes[1].fill_between(x, monthly_summary[‘savings’], where(monthly_summary[‘savings’]0), color‘lightblue’, alpha0.5) axes[1].fill_between(x, monthly_summary[‘savings’], where(monthly_summary[‘savings’]0), color‘lightcoral’, alpha0.5) axes[1].set_ylabel(‘结余 (元)’) axes[1].set_title(‘月度结余趋势正为储蓄负为超支’) axes[1].tick_params(axis‘x’, rotation45) axes[1].grid(True, linestyle‘—’, alpha0.5) plt.tight_layout() plt.show()这张组合图信息量巨大上图一眼就能看出哪个月是大额支出月比如双11下图则清晰地展示了财务健康状况储蓄线是否在0轴以上稳步上升。4.3 深度下钻特定类别消费分析当我们发现“餐饮”或“购物”是支出大头时自然会想深入了解。这时可以对特定类别进行时间序列下钻和金额分布分析。import seaborn as sns # 聚焦“餐饮”类别 food_df expense_df[expense_df[‘category’] ‘餐饮’].copy() food_df[‘day_of_week’] food_df[‘date’].dt.dayofweek # 0周一, 6周日 food_df[‘hour’] food_df[‘date’].dt.hour # 绘制餐饮消费分布图 fig, axes plt.subplots(1, 2, figsize(15, 5)) # 左图一周内每日餐饮消费总额 weekday_map {0: ‘周一’, 1: ‘周二’, 2: ‘周三’, 3: ‘周四’, 4: ‘周五’, 5: ‘周六’, 6: ‘周日’} food_by_weekday food_df.groupby(‘day_of_week’)[‘amount’].sum().abs() food_by_weekday.index food_by_weekday.index.map(weekday_map) axes[0].bar(food_by_weekday.index, food_by_weekday.values, color‘orange’) axes[0].set_title(‘餐饮消费周内分布’) axes[0].set_ylabel(‘消费金额 (元)’) axes[0].tick_params(axis‘x’, rotation45) # 右图餐饮消费金额分布箱线图观察消费水平与异常值 sns.boxplot(yfood_df[‘amount’].abs(), axaxes[1], color‘lightyellow’) axes[1].set_title(‘单笔餐饮消费金额分布’) axes[1].set_ylabel(‘金额 (元)’) plt.tight_layout() plt.show()通过这个分析你可能会发现“周五晚上和周末的餐饮开销显著高于工作日”或者“大部分餐饮消费在20-80元区间但偶尔有几次超过200元的大餐”。这些洞察对于制定预算比如设定周末餐饮预算上限非常有帮助。4.4 预算与实际对比分析如果你有预算那么这个对比能让你清晰地看到计划与现实的差距。# 假设你有一个预算字典 monthly_budget { ‘餐饮’: 1500, ‘交通’: 500, ‘购物’: 1000, ‘生活缴费’: 800, ‘娱乐’: 300, ‘其他’: 500 } # 计算当月实际支出 current_month df_clean[‘month’].max() # 取最近一个月 current_month_expense expense_df[expense_df[‘month’] current_month] actual_by_category current_month_expense.groupby(‘category’)[‘amount’].sum().abs() # 准备对比数据 comparison_data [] for category, budget in monthly_budget.items(): actual actual_by_category.get(category, 0) comparison_data.append({ ‘category’: category, ‘budget’: budget, ‘actual’: actual, ‘difference’: actual - budget # 正数表示超支 }) comparison_df pd.DataFrame(comparison_data) # 绘制预算与实际对比柱状图 fig, ax plt.subplots(figsize(12, 6)) x range(len(comparison_df)) width 0.35 ax.bar([i - width/2 for i in x], comparison_df[‘budget’], width, label‘预算’, color‘lightgray’, edgecolor‘black’) ax.bar([i width/2 for i in x], comparison_df[‘actual’], width, label‘实际’, color‘lightcoral’, edgecolor‘black’) # 标记超支部分用红色误差线或箭头标注 for i, row in comparison_df.iterrows(): if row[‘difference’] 0: ax.text(i, max(row[‘budget’], row[‘actual’]) 50, f“{row[‘difference’]:.0f}”, ha‘center’, color‘red’, fontweight‘bold’) ax.set_xticks(x) ax.set_xticklabels(comparison_df[‘category’], rotation45) ax.set_ylabel(‘金额 (元)’) ax.set_title(f’{current_month} 预算与实际支出对比’) ax.legend() ax.grid(True, axis‘y’, linestyle‘—’, alpha0.3) plt.tight_layout() plt.show()这张图能让你瞬间抓住重点哪个类别是“预算杀手”。超支的金额被清晰地标注在柱子上方督促你下个月做出调整。5. 工程化与自动化实践一次性的分析很棒但让脚本定期自动运行才能形成持续的个人财务监控系统。5.1 源码结构组织一个良好的项目结构能让代码更易维护和扩展。我建议的目录结构如下personal_finance_analysis/ ├── data/ # 存放原始账单CSV文件 │ ├── alipay_202405.csv │ ├── wechat_202405.csv │ └── ... ├── config/ # 配置文件 │ └── category_rules.json # 分类规则映射可独立出来方便修改 ├── output/ # 输出目录 │ ├── charts/ # 生成的图表图片 │ └── report_202405.html # 生成的HTML报告 ├── src/ # 源代码 │ ├── data_loader.py # 数据加载与清洗模块 │ ├── categorizer.py # 消费分类模块 │ ├── analyzer.py # 数据分析模块 │ ├── visualizer.py # 可视化图表生成模块 │ └── main.py # 主程序入口 ├── requirements.txt # 项目依赖包列表 └── README.md # 项目说明文档通过模块化设计main.py的流程会非常清晰# main.py 示例 from src.data_loader import load_and_clean_data from src.categorizer import categorize_transactions from src.analyzer import run_analysis from src.visualizer import generate_all_charts, generate_html_report def main(): # 1. 加载清洗 df load_and_clean_data(‘./data/’) # 2. 分类 df categorize_transactions(df) # 3. 分析计算各种聚合数据 analysis_results run_analysis(df) # 4. 可视化并生成报告 generate_all_charts(analysis_results, output_path‘./output/charts/’) generate_html_report(analysis_results, ‘./output/report_latest.html’) print(“分析完成报告已生成。”) if __name__ ‘__main__’: main()5.2 自动化报告生成定期手动运行脚本并查看图片还是不够方便。我们可以用Jinja2模板引擎将分析结果和图表自动嵌入到一个HTML报告中并定期通过邮件发送给自己或保存到云盘。# 在visualizer.py中增加生成HTML报告的函数 import jinja2 from datetime import datetime def generate_html_report(analysis_results, output_path): “”“生成一个美观的HTML总结报告”“” # 准备模板数据 context { ‘report_date’: datetime.now().strftime(‘%Y年%m月%d日’), ‘total_income’: analysis_results[‘total_income’], ‘total_expense’: analysis_results[‘total_expense’], ‘savings_rate’: analysis_results[‘savings_rate’], ‘top_expense_category’: analysis_results[‘top_category’], ‘monthly_trend_chart’: ‘./charts/monthly_trend.png’, # 图表路径 ‘category_pie_chart’: ‘./charts/category_pie.png’, # … 其他分析结果和图表路径 } # 读取HTML模板 env jinja2.Environment(loaderjinja2.FileSystemLoader(‘./templates/’)) template env.get_template(‘report_template.html’) # 渲染并写入文件 html_content template.render(**context) with open(output_path, ‘w’, encoding‘utf-8’) as f: f.write(html_content)配合系统的定时任务如Linux的cron或Windows的“任务计划程序”每月1号自动运行脚本生成报告并发送邮件你就拥有了一个完全自动化的个人财务分析机器人。5.3 常见问题与排查技巧实录在实际运行中你肯定会遇到各种问题。下面是我踩过坑后总结的速查表问题现象可能原因解决方案运行代码报错KeyError列名映射不对代码中的列名与实际CSV文件表头不匹配。使用print(df.columns)查看原始列名修改column_mapping字典。日期解析出错全是NaT原始数据日期格式五花八门如“2024/5/1”、“2024-05-01 下午”、“01-May-24”。使用pd.to_datetime(df[‘date’], format‘%Y/%m/%d’)指定明确格式或尝试dayfirstTrue等参数。最稳妥是先查看几行原始数据。金额列无法转为数字金额列含有中文括号、空格、货币符号等非数字字符。在转换前加强清洗df[‘amount’] df[‘amount’].astype(str).str.replace(‘[¥¥$, ]’, ‘’, regexTrue).astype(float)。分类结果大部分是“其他”分类关键词字典 (category_rules) 不完善或描述信息太简略。1. 先运行一次将分类为“其他”的记录导出到Excel查看。2. 根据这些记录的描述补充关键词到对应类别。这是一个迭代优化的过程。图表中文显示为方框Matplotlib默认字体不包含中文。在代码开头添加字体设置plt.rcParams[‘font.sans-serif’] [‘SimHei’, ‘Microsoft YaHei’]plt.rcParams[‘axes.unicode_minus’] False生成的图片模糊保存图片时DPI设置过低。在plt.savefig(‘chart.png’, dpi300, bbox_inches‘tight’)中将dpi提高到300或更高。数据量变大后程序变慢对大数据集使用循环操作而非Pandas的向量化操作。避免在DataFrame上使用apply循环尽量使用Pandas内置的字符串方法 (str.contains) 和映射 (map)。分类函数是性能瓶颈可考虑优化或对稳定数据预分类。一个关键的调试技巧在数据清洗的每个关键步骤后使用df.to_csv(‘debug_step_1.csv’, indexFalse)将中间结果输出到文件。用Excel打开检查能非常直观地发现哪一步处理出了问题。6. 从分析到行动让数据产生实际价值图表很漂亮数字很清晰但如果不转化为行动这一切就只是数字游戏。我根据自己的分析结果形成了几个简单的行动准则设立“警戒线”在月度趋势图上我为“餐饮”和“购物”这两个弹性支出大类画了一条预算线。当柱状图接近这条线时我就会下意识地控制相关消费。管理“消费脉冲”通过分析发现我每周四晚上和周六下午的线上购物消费异常活跃。于是我在这两个时间段刻意安排了其他活动如运动、看书减少打开购物APP的机会。优化“支付工具”分析显示某张信用卡的消费频率和金额远高于其他且多用于娱乐消费。我将这张卡从移动支付中解绑只用于计划内的大额消费有效减少了随意支出。定期“审计”异常每月报告生成后我会快速浏览“单笔金额TOP10”的支出列表。对于任何一笔感觉“当时是不是冲动了”的消费记录下来。几个月的记录叠加就能清晰看到自己的“冲动消费”模式是什么比如深夜、情绪低落时。这个Python项目给我的不仅仅是一堆图表而是一个客观的财务反馈系统。它把感性的“感觉钱不够花”变成了理性的“餐饮超预算30%主要因为周末外出就餐次数增加”。决策从此有了依据。本文还有配套的精品资源点击获取
返回列表