我的目的是搭建一个个人账单可视化面板,预期目标如下:
1、备忘录中的原始非结构化数据:
首先展示我的非结构化账单,内容已进行脱敏,我习惯使用ios的备忘录记录我的账单,以日期、日记、交易明细+金额进行记录,为了进行power bi可视化,我需要录入excel结构化下来;一条条录入实在太麻烦,我采用简单规则化的方式以便使用python进行快速结构化,规则如下:
日期;日记
交易1;金额
交易2;金额
默认金额是支出,如果是收入在金额后分号加一个收入即可;规则化如下:
2、python结构化
接下来使用python快速结构化,代码如下:
import pandas as pd
from datetime import datetime
# 假设您的文本数据存储在名为'expenses.txt'的文件中
file_path = '2024年规则化账单.txt'
year = 2024
# 读取文件内容
with open(file_path, 'r', encoding='utf-8') as file:
text = file.read()
# 使用空行将文本数据按天分隔开保存到列表
days_data = text.strip().split('\n\n')
# 创建一个空的DataFrame
df = pd.DataFrame(columns=['日期', '金额', '类型明细', '日记', '交易方向'])
# 循环列表读取当天的文本内容
for i, day_data in enumerate(days_data, 1): # 从1开始计数
# 按照行将当天数据分割成列表
day_lines = day_data.strip().split('\n')
# 读取列表第一个值,判断是否有分号“;”
if '\uFF1B' in day_lines[0]:
date, diary = day_lines[0].split('\uFF1B')
else:
date, diary = day_lines[0], 'nan'
# 循环读取列表第二个值到最后一个值
for j, expense in enumerate(day_lines[1:], 2): # 从2开始计数,因为第一个元素是日期
try:
xiaofei = expense.split('\uFF1B')
if len(xiaofei) == 3:
Type_Detail = xiaofei[0] # 非数字部分
Amount = float(xiaofei[1]) # 数字部分
Amount_type = xiaofei[2]
else:
Type_Detail = xiaofei[0] # 非数字部分
Amount = float(xiaofei[1]) # 数字部分
Amount_type = "支出"
# 将数据写入DataFrame
df = df.append({
'日期': date,
'金额': Amount,
'类型明细': Type_Detail,
'日记': diary,
'交易方向': Amount_type
}, ignore_index=True)
except Exception as e:
# 打印出错的date和expense
print(f"Error on date '{date}' and expense: '{expense}'")
print(f"Error message: {str(e)}")
# 将日期列的值转换为包含年份的完整日期格式
df['日期'] = pd.to_datetime(f"{year}-" + df['日期'].astype(str), format='%Y-%m-%d')
# 将日期格式化为'年月日'格式
df['日期'] = df['日期'].dt.strftime('%Y/%m/%d')
# 显示DataFrame
df
运行结果如下:
可以看到效果非常好!接下来进行类别标注
3、类别标注,可选用机器学习方法
为了展示消费类型每个月的环形图,需要添加第六个变量即消费类型
我采用excel的下拉列表(数据验证功能)进行一一匹配
标注完成如下:
如果数据标注的足够多,可以使用语义分类模型进行自动标注,比如多项式贝叶斯根据类别明细对类型进行自动分类。
4、power bi可视化
本节内容参考b站视频:Powerbi入门案例教程——中国城市经济综合数据分析,完成你的第一个可视化。_哔哩哔哩_bilibili
将excel导入power bi,导入要进行如下操作:
1、将不是标题行的表格,使用编辑器设置一下
2、通过复制日期列使用编辑器操作出月度列和年度列:
3、建立总收入、总支出等总和度量值
这里我们需要计算出每个月的交易方向为收入的金额总和,使用DAX公式:总收入=sumx(filter('消费明细','消费明细'['交易方向'] = '收入'),'消费明细'['金额'])即可
4、使用切片器和卡片和环形图排练看板即可!
5、当然,python可视化也是可以的:
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import HTML
# 请替换为您的文件路径
path = "/Users/luoziweiyu/anaconda3文件夹/小工具/账单系列/2024年结构化标注化账单明细.xlsx"
# 询问用户查询几月份的面板
month = int(input("请输入您想查询的月份(1-12):"))
# 读取Excel文件
df = pd.read_excel(path)
# 将日期列从字符串格式转换为datetime格式
df['日期'] = pd.to_datetime(df['日期'], format='%Y/%m/%d')
# 筛选出指定月份的记录
df_filtered = df[df['日期'].dt.month == month]
# 根据类型列分组计算金额列的总和
grouped = df_filtered.groupby('类型')['金额'].sum()
plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
# 创建一个环形图
fig, ax = plt.subplots(figsize=(15, 8)) # 增大图表尺寸
wedges, texts, autotexts = ax.pie(grouped, labels=grouped.index, autopct='%1.1f%%', startangle=90, pctdistance=0.6)
# 确保饼图是圆形的
ax.axis('equal')
# 自定义外围的百分比标签
for text in texts:
text.set_size(15) # 设置字体大小
text.set_color('green') # 设置字体颜色
# 自定义图例
plt.legend(wedges, grouped.index, title="类型", loc="center right",prop={'size': 15})
plt.title(f"{month}月的账单环形图如下:")
# 绘制环形图下方的HTML表格,显示收入和支出的总和
income_total = df_filtered[df_filtered['交易方向'] == '收入']['金额'].sum()
expense_total = df_filtered[df_filtered['交易方向'] == '支出']['金额'].sum()
plt.show()
# 生成HTML表格
html_table = """
<table border="1" style="width:50%">
<tr>
<th>交易方向</th>
<th>总金额</th>
</tr>
<tr>
<td>收入</td>
<td>{:.2f}</td>
</tr>
<tr>
<td>支出</td>
<td>{:.2f}</td>
</tr>
</table>
""".format(income_total, expense_total)
# 在Jupyter Notebook中显示HTML表格
display(HTML(html_table))