python清洗支付宝微信账单+powerbi实现交互式账单可视化

前言

   消费降级,经济下行,购买力下降......最近这些字眼深深刺痛了我的贫穷且清澈的双眼,作为抖音经济学家的我开始感到了压迫感,故天降大任于斯人也......以上全是玩笑话,本人主要是想学习了解一下python这门语言,顺便看看有没有好的代码参考一下,于是b站搜了一下发现一个up主的代码项目挺好的,还能继续我那未竟的记账梦,守住钱包基本盘。

  然而,在评论区下载完后发现不知道为啥用不了,应该年代过于久远的原因吧,翻了评论区也留言最后好久也没有更新,只好自力更生了,亲历亲为了,在缝缝补补后继续分享出来给大家。

最终效果

这是清洗完数据后导入powerbi后的一个可视化交互界面,没做界面美化,比较懒,可以看一下它在网页端的展示效果(数据源为本人部分消费片段截取)

代码分享

这是清洗数据的代码分享,代码内已含有原作者信息,我只做了部分修改,若想使用其来记账,建议去看看原作者的视频,视频地址在代码行里。

# Version:      2.1
# StartTime:   2021/1/6 12:30
# Finished:    2021/1/7 20:30
# Author:      MickLife
# B站:         https://space.bilibili.com/38626658

# 补充内容大致如下:
# 修改了代码中支付宝和微信csv文件列名
# 支付宝csv文件使用gbk编码读取
# 删除了文字小尾巴使其在PowerBi上更具有可读性
# 增加了一些辅助性质的打印信息
# 修改时间:2023/10/16


import pandas as pd
import openpyxl
import tkinter.filedialog
import msvcrt

#设置显示的最大列、宽等参数,消掉打印不完全中间的省略号
pd.set_option('display.max_columns', 1000)
pd.set_option('display.width', 1000)
pd.set_option('display.max_colwidth', 1000)

def strip_in_data(data):  # 把列名中和数据中首尾的空格都去掉。
    data = data.rename(columns={column_name: column_name.strip() for column_name in data.columns})
    data = data.apply(lambda x: x.map(lambda y: y.strip().strip('¥') if isinstance(y, str) else y))
    return data

def read_data_wx():  # 获取微信数据 #(path)
    d_wx = pd.read_csv(path_wx, header=16, skipfooter=0, encoding='utf-8')  # 数据获取,微信 #把path改为path_wx了,-sig
    d_wx = d_wx.iloc[:, [0, 4, 7, 1, 2, 3, 5]]  # 按顺序提取所需列
    d_wx = strip_in_data(d_wx)  # 去除列名与数值中的空格。
    a = d_wx.iloc[:, 0]
    b = pd.to_datetime(a)
    date_only = b.dt.date
    d_wx.iloc[:, 0] = date_only  # 日期类型更改
    c = d_wx.iloc[:, 6]
    d = c.astype('float64')
    d_wx.iloc[:, 6] = d  # 浮点数类型更改
    d_wx = d_wx.drop(d_wx[d_wx['收/支'] == '/'].index)  # 删除'收/支'为'/'的行
    d_wx.rename(columns={'当前状态': '支付状态', '交易类型': '类型', '金额(元)': '金额'}, inplace=True)  # 修改列名称
    d_wx.insert(1, '来源', "微信", allow_duplicates=True)  # 添加微信来源标识
    len1 = len(d_wx)
    print("成功读取 " + str(len1) + " 条「微信」账单数据\n")
    return d_wx

def read_data_zfb():  # 获取支付宝数据
    # 读取ANSI编码的CSV文件
    d_zfb = pd.read_csv(path_zfb, header=4, skipfooter=7, encoding='gbk', engine='python')
    d_zfb = d_zfb.iloc[:, [2, 10, 11, 6, 7, 8, 9]]  # 按顺序提取所需列
    d_zfb = strip_in_data(d_zfb)  # 去除列名与数值中的空格
    g = d_zfb.iloc[:, 0]
    b = pd.to_datetime(g)
    date_only = b.dt.date
    d_zfb.iloc[:, 0] = date_only    # 修改时间类型
    c = d_zfb.iloc[:, 6]
    d = c.astype('float64')
    d_zfb.iloc[:, 6] = d  # 修改浮点数类型
    d_zfb = d_zfb.drop(d_zfb[d_zfb['收/支'] == '不计收支'].index)  # 删除'收/支'为'不计收支'的行
    d_zfb.rename(columns={'交易创建时间': '交易时间', '商品名称': '商品', '金额(元)': '金额', '交易状态': '支付状态'}, inplace=True)  # 修改列名称
    d_zfb.insert(1, '来源', "支付宝", allow_duplicates=True)  # 添加支付宝来源标识
    len1 = len(d_zfb)
    print("成功读取 " + str(len1) + " 条「支付宝」账单数据\n")
    return d_zfb

def add_cols(data):  # 增加3列数据
    # 逻辑1:取值-1 or 1。-1表示支出,1表示收入。
    data.insert(8, '逻辑1', -1, allow_duplicates=True)  # 插入列,默认值为-1
    for index in range(len(data.iloc[:, 2])):  # 遍历第3列的值,判断为收入,则改'逻辑1'为1
        if data.iloc[index, 2] == '收入':
            data.iloc[index, 8] = 1

    # 逻辑2:取值0 or 1。1表示计入,0表示不计入。
    data.insert(9, '逻辑2', 1, allow_duplicates=True)  # 插入到第10列,默认值为1
    for index in range(len(data.iloc[:, 3])):  # 遍历第4列的值,判断为资金流动,则改'逻辑2'为0
        if data.iloc[index, 3] == '交易成功':
            data.iloc[index, 9] = 1
    # 月份
    data.insert(1, '月份', 0, allow_duplicates=True)  # 插入列,第二列,默认值为0
    for index in range(len(data.iloc[:, 0])):
        time = data.iloc[index, 0]
        data.iloc[index, 1] = time.month  # 访问月份属性的值,赋给这月份列

    # 乘后金额
    data.insert(11, '乘后金额', 0, allow_duplicates=True)  # 插入列,默认值为0
    for index in range(len(data.iloc[:, 8])):  # 遍历逻辑1
        money = data.iloc[index, 8] * data.iloc[index, 9] * data.iloc[index, 10]
        data.iloc[:, 11] = data.iloc[:, 11].astype(float)
        data.iloc[index, 11] = money  # 插入乘后金额到12列
    return data
# 从这里开始执行代码
if __name__ == '__main__':

    # 路径设置
    print('提示:请在弹窗中选择要导入的【微信】账单文件\n')
    path_wx = tkinter.filedialog.askopenfilename(title='选择要导入的微信账单:', filetypes=[('所有文件', '.*'), ('csv文件', '.csv')])
    if path_wx == '':  # 判断是否只导入了微信或支付宝账单中的一个
        cancel_wx = 1
        print('wx导入失败')   # 本人
    else:
        cancel_wx = 0
        print('wx导入成功')  # 本人

    print('提示:请在弹窗中选择要导入的【支付宝】账单文件\n')
    path_zfb = tkinter.filedialog.askopenfilename(title='选择要导入的支付宝账单:', filetypes=[('所有文件', '.*'), ('csv文件', '.csv')])
    if path_zfb == '':  # 判断是否只导入了微信或支付宝账单中的一个
        cancel_zfb = 1
        print('zfb导入失败')  # 本人
    else:
        cancel_zfb = 0
        print('zfb导入成功')  # 本人

    while cancel_zfb == 1 and cancel_wx == 1:
        print('\n您没有选择任何一个账单!     请按任意键退出程序')
        ord(msvcrt.getch())

    path_account = tkinter.filedialog.askopenfilename(title='选择要导出的目标账本表格:', filetypes=[('所有文件', '.*'), ('Excel表格', '.xlsx')])
    while path_account == '':  # 判断是否选择了账本
        print('\n年轻人,不选账本怎么记账?      请按任意键退出程序')
        ord(msvcrt.getch())
        # path空值同样失败
        # path_account 是合并输出数据

    path_write = path_account

    # 判断是否只导入了微信或支付宝账单中的一个
    if cancel_wx == 1:
        data_wx = pd.DataFrame()
    else:
        data_wx = read_data_wx()
    if cancel_zfb == 1:
        data_zfb = pd.DataFrame()
    else:
        data_zfb = read_data_zfb()

        type_c = 'data_wx的类型:' + str(type(data_wx))
        print(type_c)

        print('******************************')

        type_d = 'data_zfb的类型:' + str(type(data_zfb))
        print(type_c)

    data_merge = pd.concat([data_wx, data_zfb], axis=0)  # 上下拼接合并表格
    print(data_merge)
    data_merge = add_cols(data_merge)  # 新增 逻辑、月份、乘后金额 3列
    print("已自动计算乘后金额和交易月份,已合并数据")
    merge_list = data_merge.values.tolist()  # 格式转换,DataFrame->List
    workbook = openpyxl.load_workbook(path_account)  # openpyxl读取账本文件

    sheet = workbook['明细']
    max_data_row = 0
    for row in sheet.iter_rows(min_row=1, max_row=sheet.max_row):  # 从第二行开始遍历
        if all(cell.value is None or cell.value == '' for cell in row):
            break
        max_data_row = row[0].row

    print('\n「明细」 sheet 页已有 ' + str(max_data_row) + ' 行数据,将在末尾写入数据')

    for row in merge_list:
        sheet.append(row)  # 将每一行数据追加到工作表中

    workbook.save(path_write)  # 保存
    print("\n成功将数据写入到 " + path_write)
    print("\n运行成功!write successfully!    按任意键退出")
    ord(msvcrt.getch())


后续想法

清洗数据的代码还是有些不足之处,比如重复插入相同数据也照样合并重复的数据;以及手动选择分类标签太麻烦;还有就是作为记账交互界面,应该要有理财方面的可视化界面的,例如股票,资金,保险不知道,应该算支出项,这样才能更加清晰地了解自己的个人资产。另外还有手动记账也是麻烦,虽然可以控制自己将大部分资金流动都在支付宝和微信中流动,但仍有少部分是不能避免的要从银行卡里产生收支项的,这个还好,基本每个银行也都能导出账单文件,但是特别是有些支付方式,是无法导出账单文件的,例如数字人民币钱包就暂时没有这个功能。这些都是要考虑的。

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现 Python 后端和微信小程序的交互,可以通过以下步骤: 1. 搭建 Python 后端,使用 Flask 框架创建 API 接口,提供数据服务。 2. 在微信小程序中,使用 wx.request() 方法向 Python 后端发送请求,并获取数据。 3. 在 Python 后端中,解析请求数据,并根据请求返回相应的数据。 具体来说,可以按照以下步骤实现: 1. 在 Python 后端中,安装 Flask 框架,并创建一个简单的 API 接口,如下所示: ```python from flask import Flask, request app = Flask(__name__) @app.route('/api/data', methods=['GET']) def get_data(): # 处理请求数据 data = {'name': '张三', 'age': 20} return data ``` 2. 在微信小程序中,使用 wx.request() 方法向 Python 后端发送请求,并获取数据,如下所示: ```javascript wx.request({ url: 'http://yourserver.com/api/data', success: function(res) { console.log(res.data) // 打印获取到的数据 } }) ``` 3. 在 Python 后端中,解析请求数据,并根据请求返回相应的数据,如下所示: ```python from flask import Flask, request app = Flask(__name__) @app.route('/api/data', methods=['GET']) def get_data(): # 处理请求数据 # 解析请求参数 name = request.args.get('name') age = request.args.get('age') # 返回数据 data = {'name': name, 'age': age} return data ``` 这样,就可以实现 Python 后端和微信小程序的交互了。当然,还需要考虑数据安全等问题,例如对请求进行认证、限制请求频率等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值