• 【毕业设计】后端实现——账单通过关键词简单分析收支


    🌈据说,看我文章时 关注、点赞、收藏帅哥美女们 心情都会不自觉的好起来。

    前言:
    🧡作者简介:大家好我是 user_from_future ,意思是 “ 来自未来的用户 ” ,寓意着未来的自己一定很棒~
    ✨个人主页:点我直达,在这里肯定能找到你想要的~
    👍专栏介绍:个人记账分析系统 ,专门记录制作过程,每天进步一点点~

    想看往期历史文章,可以浏览此博文: 历史文章目录,后续所有文章发布都会同步更新此博文~

    人生苦短,我用python

    后端实现——账单通过关键词简单分析收支

    说明

    在上一次获取到的数据中,不难发现不是所有都被列为收入/支出的,还有一部分比如花呗的还款成功实际上算是第二次记录了,之前每次花呗消费已经在账单里了,这些是要去除,还有收/支为其他的,要结合其他列的关键词进行判断,本文就是来处理这里数据的。

    预设计

    先客观尝试判断这样是否可以实现:

    wx = alipay_analysis(open('data/微信支付账单(XXXXXXXX-XXXXXXXX).csv', 'r').read())
    for w in wx['data']:
        if w[4] == '收入':
            print('+' + w[5])
        elif w[4] == '支出':
            print('-' + w[5])
        else:
            if '充值' in w[1]:
                print('+' + w[5])
            else:
                print(w)
    zfb = alipay_analysis(open('data/alipay_record_XXXXXXXX_XXXXXX.csv', 'r').read())
    for z in zfb['data']:
        if z[0] == '收入':
            if z[6] != '交易关闭':
                print('+' + z[5])
            else:
                print(z)
        elif z[0] == '支出':
            if z[6] != '交易关闭':
                print('-' + z[5])
            else:
                print(z)
        else:
            if z[6] in ['退款成功'] or z[7] in ['投资理财']:
                print('+' + z[5])
            elif z[6] in ['还款成功', '信用服务使用成功', '解冻成功']:
                print('-' + z[5])
            else:
                print(z)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    简单处理后,发现满足我们的需求了,所有账单已经明确是收入还是支出了,接下来就设计通用规则,并能方便修改。

    设计规则

    由于涉及到每一列关键词判断,所以设计了一套判断规则:

    {
        title: {  # 标题
            '+in': []  # 完全相等时判断为收入
            '+have': []  # 部分匹配时判断为收入
            '-in': []  # 完全相等时判断为支出
            '-have': []  # 部分匹配时判断为支出
            'ignore': []  # 忽略交易的关键字(比如交易关闭)
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这样包括了各种目前发现的可能的情况,如果不够,以后可以添加条目。
    优先级为 ignore > in > have
    ignore 为忽略账单的部分,比如花呗还款;
    in 为固定账单中的词语,可以判断固定类别;
    have 为账单中可能包含的关键词,可以灵活判断。
    + 代表收入,- 代表支出。
    默认在 “ 收/支 ” 列判断有没有收入和支出作为判断:

    def check_in_out_default(alipay: list):
        """
        生成默认的规则字典
        :param alipay: alipay_analysis 中的 table
        :return: 默认的规则字典(优先级:ignore > in > have)
            {
                title: {  # 标题
                    '+in': []  # 完全相等时判断为收入
                    '+have': []  # 部分匹配时判断为收入
                    '-in': []  # 完全相等时判断为支出
                    '-have': []  # 部分匹配时判断为支出
                    'ignore': []  # 忽略交易的关键字(比如交易关闭)
                }
            }
        """
        # print(json.dumps(check_in_out_default(table), indent=4, ensure_ascii=False))
        # return {title: {'+in': ['收入'] if title == '收/支' else [], '+have': [], '-in': ['支出'] if title == '收/支' else [], '-have': [], 'ignore': []} for title in alipay[0]}
        return {title: {'+in': ['收入'], '+have': [], '-in': ['支出'], '-have': [], 'ignore': []} for title in alipay[0] if title == '收/支'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    默认一般返回 {'收/支': {'+in': ['收入'], '+have': [], '-in': ['支出'], '-have': [], 'ignore': []}} ,根据这个拓展就可以。
    我目前的规则设置为:

    # 微信规则
    wx_rules = {
        "交易类型": {
            "+in": [],
            "+have": ["充值"],
            "-in": [],
            "-have": [],
            "ignore": []
        },
        "收/支": {
            "+in": ["收入"],
            "+have": [],
            "-in": ["支出"],
            "-have": [],
            "ignore": []
        }
    }
    # 支付宝规则
    zfb_rules = {
        "收/支": {
            "+in": ["收入"],
            "+have": [],
            "-in": ["支出"],
            "-have": [],
            "ignore": []
        },
        "交易状态": {
            "+in": ["退款成功"],
            "+have": [],
            "-in": ["信用服务使用成功", "解冻成功"],
            "-have": [],
            "ignore": ["交易关闭", "还款成功"]
        },
        "交易分类": {
            "+in": ["投资理财"],
            "+have": [],
            "-in": [],
            "-have": [],
            "ignore": []
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    目前用这套规则后,数据分类正常,打算在个人用户里可以设置处理这个。

    设计处理函数

    def check_in_out(alipay: list, rules: dict = None):
        """
        分析收入支出数据
        :param alipay: alipay_analysis 中的 table
        :param rules: 规则字典(优先级:ignore > in > have)
        :return: table, unchecked_table
        """
        if not rules:
            rules = check_in_out_default(alipay)
        titles = alipay[0]
        table = [titles]
        indexs = {titles.index(title): rules[title] for title in rules}
        for row in alipay:
            for index in indexs:
                if row[index] in indexs[index].get('ignore', []):
                    continue
                if row[index] in indexs[index].get('+in', []):
                    row[titles.index('收/支')] = '+'
                    table.append(row)
                    continue
                if row[index] in indexs[index].get('-in', []):
                    row[titles.index('收/支')] = '-'
                    table.append(row)
                    continue
                for item in indexs[index].get('+have', []):
                    if item in row[index]:
                        row[titles.index('收/支')] = '+'
                        table.append(row)
                        break
                else:
                    continue
                for item in indexs[index].get('-have', []):
                    if item in row[index]:
                        row[titles.index('收/支')] = '-'
                        table.append(row)
                        break
                else:
                    continue
        return table, [a for a in alipay[1:] if a[titles.index('收/支')] not in ['+', '-']]
    
    
    ok, failed = check_in_out(alipay_analysis(open('data/alipay_record_20221104_173011.csv', 'r').read())['data'], zfb_rules)
    ok, failed = check_in_out(alipay_analysis(open('data/微信支付账单(20220904-20221104).csv', 'r').read())['data'], wx_rules)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    返回处理好的列表和未被处理的列表,然后前端可以根据未处理列表信息进行判断修改规则。

  • 相关阅读:
    Centos7系统下Docker的安装与配置
    CUDA 编程简介
    关于电脑卡死如何开机、F8、安全模式
    代码随想录算法训练营Day32 | 贪心算法(2/6) Leetcode 122.买卖股票的最佳时机 II 55. 跳跃游戏 45.跳跃游戏II
    【奇思妙想】【节省磁盘空间】我有一些文件,我不想移动它们,但又想节省磁盘空间,该怎么做呢?
    三个高级参数:out、ref、params(本章为params参数)
    3基于MATLAB的齿轮啮合仿真,可根据需要调节齿轮参数,实现齿轮啮合转动动态过程。程序已调通,可直接运行。
    用servlet写一个hello word
    DC36V 3A降压芯片FP6150BXR中文说明,附常规问题,布板说明
    达梦数据库安装和使用
  • 原文地址:https://blog.csdn.net/user_from_future/article/details/127824443