直接上源代码:

#!/usr/bin/env python3
# -*- coding:utf-8 -*-
"""
Created on 2020/8/6 21:57
@author: Miracle
@blog : https://blog.csdn.net/weixin_39633383
@github: https://github.com/Mr-Miracle
"""
from tkinter import *
from tkinter import messagebox, filedialog
from tkinter.ttk import Progressbar
import pandas as pd
import time
LOG_LINE_NUM = 0
columns_1603 = ['投资组合代码','投资组合名称','报告日期','流动性资产-银行活期存款市值(元)','流动性资产-银行活期存款占净资产比例(%)','流动性资产-中央银行票据市值(元)','流动性资产-中央银行票据占净资产比例(%)','流动性资产-一年期以内(含一年)定期存款或协议存款市值(元)','流动性资产-一年期以内(含一年)定期存款或协议存款占净资产比例(%)','流动性资产-买入返售金融资产市值(元)','流动性资产-买入返售金融资产占净资产比例(%)','流动性资产-货币市场基金市值(元)','流动性资产-货币市场基金占净资产比例(%)','流动性资产-货币型养老金产品市值(元)','流动性资产-货币型养老金产品占净资产比例(%)','流动性资产-清算备付金市值(元)','流动性资产-清算备付金占净资产比例(%)','流动性资产-应收证券清算款市值(元)','流动性资产-应收证券清算款占净资产比例(%)','流动性资产-其他流动性资产市值(元)','流动性资产-其他流动性资产占净资产比例(%)','流动性资产占净资产比例 (%)','固定收益类资产-一年期以上定期存款/协议存款市值(元)','固定收益类资产一年期以上定期存款/协议存款占净资产比例(%)','固定收益类资产-国债市值(元)','固定收益类资产-国债占净资产比例(%)','固定收益类资产-金融债市值(元)','固定收益类资产-金融债占净资产比例(%)','固定收益类资产-企业(公 司)债市值(元)','固定收益类资产-企业(公 司)债占净资产比例(%)','固定收益类资产-短期融资券市值(元)','固定收益类资产-短期融资券占净资产比例(%)','固定收益类资产-中期票据市值(元)','固定收益类资产-中期票据占净资产比例(%)','固定收益类资产-可转换债券(含分离交易可转换债)市值(元)','固定收益类资产-可转换债券(含分离交易可转换债)占净资产比例(%)','固定收益类资产-债券基金市值(元)','固定收益类资产-债券基金占净资产比例(%)','固定收益类资产-商业银行理财产品市值(元)','固定收益类资产-商业银行理财产品占净资产比例 (%) ','固定收益类资产-信托产品市值(元) ','固定收益类资产-信托产品占净资产比例(%) ','固定收益类资产-特定资产管理计划市值(元) ','固定收益类资产-特定资产管理计划占净资产比例 (%) ','固定收益类资产-基础设施债权投资计划市值(元)','固定收益类资产-基础设施债权投资计划占净资产 比例(%) ','固定收益类资产-固定收益型养老金产品市值(元)','固定收益类资产-固定收益型养老金产品占净资产比例(%)','固定收益类资产-混合型养老金产品市值(元)','固定收益类资产-混合型养老金产品占净资产比例 (%)','固定收益类资产-其他固定收益类资产市值(元)','固定收益类资产-其他固定收益类资产占净资产比 例(%)','固定收益类资产占净资产比例(%)','权益类资产-股票市值','权益类资产-股票占净资产比例','权益类资产-股票基金、混合基金市值','权益类资产-股票基金、混 合基金占净资产比例','权益类资产-权证(非直接投资)市值(元)','权益类资产-权证(非直接 投资)占净资产比例(%)','权益类资产-权益工具市值(元) ','权益类资产-权益工具占净资产比例(%)','权益类资产-股票型养老金产品市值(元) ','权益类资产-股票型养老金产品占净资产比例(%) ','权益类资产-其他权益类资产市值(元)','权益类资产-其他权益类资产占净资产比例(%)','权益类资产占净资产比例(%)','其他资产市值(元)','其他资产占净资产比例(%)','合计市值(元)','合计占净资产比例(%)']class DataCleaning:def __init__(self, master):self.path = StringVar()self.master = masterself.Label_0 = Label(self.master, text="1603接口数据文件选择")self.Entry_0 = Entry(self.master, width=45, textvariable=self.path)self.Button_0 = Button(self.master, text="···", command=self.select_path)self.check_var1 = IntVar()self.Checkbutton_1 = Checkbutton(self.master, text="其他市值", variable=self.check_var1, onvalue=1, offvalue=0, height=5, width=20)self.check_var2 = IntVar()self.Checkbutton_2 = Checkbutton(self.master, text="比例字段", variable=self.check_var2, onvalue=1, offvalue=0, height=5, width=20)self.Button_1 = Button(self.master, text=" 开  始 ", command=self.extract_data)self.Button_2 = Button(self.master, text=" 退  出 ", command=self.master.quit)self.log_label = Label(self.master, text="  ")self.log_data_Text = Text(self.master, width=63, height=13)  # 日志框self.Progressbar = Progressbar(self.master, value=0, mode="determinate", orient=HORIZONTAL)# 设置窗口的各种属性,布局def set_init_window(self):x = root.winfo_screenwidth()y = root.winfo_screenheight()w = 450h = 400self.master.title("数据清洗--1603接口数据核对v2.0")  # 窗口名self.master.geometry("%dx%d+%d+%d" % (w, h, (x - h) / 2.5, (y - h) / 3))  # 窗口大小及窗口弹出时的默认展示位置self.master.resizable(0, 0)  # 设置窗口宽高固定self.Label_0.grid(row=0, column=0, columnspan=2)self.Entry_0.grid(row=1, column=0, columnspan=2)self.Button_0.grid(row=1, column=2)self.Checkbutton_1.grid(row=2, column=0)self.Checkbutton_2.grid(row=2, column=1)self.Button_1.grid(row=3, column=0)self.Button_2.grid(row=3, column=1)self.log_label.grid(row=4, column=0)self.log_data_Text.grid(row=5, column=0, columnspan=3)self.Progressbar.grid(row=6, column=0, columnspan=3)# 选择文件路径def select_path(self):# 只显示所有的excel文件path_ = filedialog.askopenfilenames(filetypes=[('excel', ('.xls', '.xlsx'))])self.path.set(path_)# 获取当前时间@staticmethoddef get_now_time():current_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))return current_time# 日志动态打印def write_log_to_text(self, log_msg):global LOG_LINE_NUMcurrent_time = self.get_now_time()log_msg_in = "INFO:" + str(current_time) + " " + str(log_msg) + "\n"  # 换行if LOG_LINE_NUM <= 7:self.log_data_Text.insert(END, log_msg_in)LOG_LINE_NUM = LOG_LINE_NUM + 1else:self.log_data_Text.delete(1.0, 2.0)self.log_data_Text.insert(END, log_msg_in)# 主要的程序主体逻辑def extract_data(self):# 获取用户的输入数据file_list = self.Entry_0.get().split()  # 获取需要核对的文件listc1 = self.check_var1.get()c2 = self.check_var2.get()print(c1, c2)if not file_list:messagebox.showwarning('警告', '请先选择需要核对的文件!')else:self.write_log_to_text("正在提取数据...")self.Progressbar["value"] = 5self.master.update()# 1、提取需要核对的数据,并将其贴到同一个excel文件里list_0 = []  # Alist_1 = []  # Blist_hold = []  # 持仓数据for data_file in file_list:# 如果A的数是作业平台导出的,则执行此段if '资产分布' in data_file and '数据中心取数' not in pd.ExcelFile(data_file).sheet_names:# 读取A版1603数据文件self.write_log_to_text("提取数据中心数据(作业平台导出)")self.write_log_to_text("读取文件:" + data_file)df00 = pd.read_excel(data_file)df00['币种'] = df00['报告起始日期'].astype(str)  # 将报告日期列复制到币种列,并且格式化为文本格式df00.rename(columns={'币种': '报告日期'}, inplace=True)  # 修改列名df00['报告日期'].replace('-', '', inplace=True)  # 将日期字段格式化df0 = df00.iloc[:, 14:84]  # 取第14列至73列的数据集list_0.append(df0)# 如果A的数是人工导出的,则执行此段if ('CJDC' in data_file and '持仓' not in data_file) or '数据中心' in data_file or ('cjdc' in data_file and '持仓' not in data_file):# 读A版本的1603数据文件self.write_log_to_text("开始提取A数据(手工导出版)")self.write_log_to_text("读取文件:" + data_file)df00 = pd.read_excel(data_file)df00['CALC_PHASE'] = df00['CALC_PHASE'].str.replace('-', '')  # 将日期字段格式化文本格式df0 = df00.iloc[:, 3:73]  # 取第4列至73列的数据集list_0.append(df0)if 'HT' in data_file or 'B' in data_file or 'ht' in data_file:# 读取B版本的1603数据文件self.write_log_to_text("开始提取B版数据...(数据中心提供)")self.write_log_to_text("读取文件:" + data_file)df11 = pd.read_excel(data_file)df11['CALC_PHASE'] = df11['CALC_PHASE'].str.replace('-', '')  # 将日期字段格式化文本格式df1 = df11.iloc[:, 3:73]  # 取第4列至73列的数据集list_1.append(df1)# 如果数据是数据中心提供的系统导出的,取数则执行这段if '资产分布' in data_file and '数据中心取数' in pd.ExcelFile(data_file).sheet_names and '衡泰取数' not in pd.ExcelFile(data_file).sheet_names:self.write_log_to_text("开始提取 A、B版数据...(均由系统导出版)")self.write_log_to_text("读取文件:" + data_file)# 读取A版1603数据文件df0 = pd.read_excel(data_file, sheet_name='A取数', ).iloc[:, 2:72]  # 取第3列至73列的数据集list_0.append(df0)# 读取B版本的1603数据文件df1 = pd.read_excel(data_file, sheet_name='B取数').iloc[:, 2:72]  # 取第3列至73列的数据集list_1.append(df1)if '持仓' in data_file:self.write_log_to_text("读取持仓数据:\n" + data_file)df_hold = pd.read_excel(data_file)  # 持仓数据list_hold.append(df_hold)self.write_log_to_text("正在进行数据合并...")self.Progressbar["value"] = 15self.master.update()# 2 得到合并的结果df_center = pd.concat(list_0)  # print('合并后的数据: A-->', df_center)df_xquant = pd.concat(list_1)  # print('合并后的数据: B-->', df_xquant)if list_hold:df_hold = pd.concat(list_hold)else:df_hold = pd.DataFrame()df_xquant.columns = columns_1603  # 修改结果的列名# 组合代码的_STB后缀去掉df_xquant['投资组合代码'] = df_xquant['投资组合代码'].str.replace('_STB', '')df_center.columns = columns_1603  # 修改结果的列名# 组合代码的_STB后缀去掉df_center['投资组合代码'] = df_center['投资组合代码'].str.replace('_STB', '')self.Progressbar["value"] = 20self.master.update()# 3 对结果进行比较,将2个结果集进行内连接合并result_excel = r'1603数据核对结果_' + self.get_now_time()[0:10] + '.xlsx'write = pd.ExcelWriter(result_excel)  # 创建结果excel,将合并数据存入exceldf_xquant.to_excel(write, sheet_name='0-B', index=False, freeze_panes=(1, 3))df_center.to_excel(write, sheet_name='1-A', index=False, freeze_panes=(1, 3))del df_center['投资组合名称']df_hb = df_xquant.merge(df_center, how='inner', on=['投资组合代码', '报告日期'], )  # 将2个结果集进行内连接合并check_list = [df_hb.iloc[:, 0:3]]  # 取合并后数据的前三列self.Progressbar["value"] = 40self.master.update()for column in columns_1603:# 将同字段的_X和_Y进行相减if column not in df_hb.columns.tolist():x = column + '_x'y = column + '_y's = round(df_hb[x] - df_hb[y], 6)  # 数据项目相减,B减去A的数,并且将结果保留6位小数check_list.append(s)df_check = pd.concat(check_list, axis=1)  # 检查结果进行拼接df_check.columns = columns_1603  # 修改结果的列名print('异常数据:\n', df_check)df_check.to_excel(write, sheet_name='2-异常数据', index=False, freeze_panes=(1, 3))self.write_log_to_text("写入异常数据...")self.Progressbar["value"] = 60self.master.update()# 4 将检查结果进行整理list_3 = []  # 检查结果i = 0if c1 == 0:if_list = ['投资组合代码', '投资组合名称', '报告日期', '其他资产市值(元)', '合计市值(元)']else:if_list = ['投资组合代码', '投资组合名称', '报告日期']if c2 == 0:if_str = '比例'else:if_str = '报告日期'# print(if_list, if_str)for row, series in df_check.iteritems():  # 按列遍历异常数据表# 筛选去除其他资产、合计市值、金额比例字段,并且去除无异常的字段if (row not in if_list) and (if_str not in row) and (series.sum() != 0):i += 1j = 0str_abnormal = []for m, n in series.items():# 进行异常字段个数统计if n != 0:j += 1# 将计划层的异常数据过滤,只取组合层的异常if '计划' not in df_check.iloc[[m], [1]].values[0][0]:# 组合代码,组合名称,业务日期,异常金额市值abnormal = [df_check.iloc[[m], [0]].values[0][0], df_check.iloc[[m], [1]].values[0][0],df_check.iloc[[m], [2]].values[0][0], n]if abnormal[3] > 0:reason = B比A多这笔'else:reason = 'B比A少这笔'# 如果持仓表不为空if not df_hold.empty:data = df_hold[df_hold['F_HLM'] == n]if data.empty:str_sub = abnormal[1], abnormal[2], '差异金额:' + str(abnormal[3]), '证券代码:', '证券名称:', reasonstr_abnormal.append(str_sub)else:x = '证券代码:' + data.iloc[[0], [4]].values[0][0]  # 证券代码y = '证券名称:' + data.iloc[[0], [5]].values[0][0]  # 证券名陈str_sub = abnormal[1], abnormal[2], '差异金额:' + str(abnormal[3]), x, y, reasonstr_abnormal.append(str_sub)else:str_sub = abnormal[1], abnormal[2], '差异金额:' + str(abnormal[3]), '证券代码:', '证券名称:', reasonstr_abnormal.append(str_sub)# 将异常原因的描述list进行文本转换并换行处理abnormal = ''for s in str_abnormal:abnormal = abnormal + ','.join(s) + '\n'# 进行异常描述拼接result = [i, row, len(series), j, abnormal]list_3.append(result)df_result = pd.DataFrame(list_3)self.write_log_to_text("写入异常原因...")self.Progressbar["value"] = 80self.master.update()# 判断异常结果是否为空if df_result.empty:df_result = pd.DataFrame(columns=['序号', '字段名称', '检验笔数', '异常数', '差异原因\n(组合名称、业务日期、差异金额、证券代码、证券名称)'])self.write_log_to_text("检查完毕,没有异常!!")self.Progressbar["value"] = 90self.master.update()else:df_result.columns = ['序号', '字段名称', '检验笔数', '异常数', '差异原因\n(组合名称、业务日期、差异金额、证券代码、证券名称)']self.write_log_to_text("检查完毕!")print('检验结果为:\n', df_result)df_result.to_excel(write, sheet_name='3-检查结果', index=False, freeze_panes=(1, 0))self.write_log_to_text("正在保存文件!")self.master.update()write.save()  # 文件保存write.close()print('核对完成,文件保存为:\n', result_excel)self.write_log_to_text('文件保存为:\n'+ result_excel)self.Progressbar["value"] = 100self.master.update()if __name__ == '__main__':root = Tk()app = DataCleaning(root)# 设置根窗口默认属性app.set_init_window()root.mainloop()  # 窗口进入事件循环,保持窗口运行,否则界面不展示

程序效果图如下:

thinker 库开发的GUI程序-利用Pandas进行excel文档数据的读取和数据比对相关推荐

  1. 基于pandas实现excel文档的拆分

    import glob import pandas as pd import tkinter as tk from tkinter import filedialogdef mkdir(path):i ...

  2. pandas读取Excel文档数据

    演示视频 python读取Excel表格数据pandas读取表格read_excel函数使用_哔哩哔哩_bilibili read_excel函数 实现功能 调用python多个Excel表格数据处理 ...

  3. 使用WPS 2005的二次开发功能,是否可以成为.net导出文档的一种新途径?

    我曾经进行过.net导出Excel的开发工作,因为对导出的Excel文档的格式要求比较高,所以,选择的是.net调用COM的方式进行的开发.整个开发的过程还是比较顺利的,但对最后程序运行的结果不是很满 ...

  4. 利用Pandas拆分Excel的单元格为多行并保留其他行的数据

    利用Pandas拆分Excel的单元格为多行并保留其他行的数据 1. 需求 2. Pandas解决需求 2.1 准备工作 2.2 Python程序执行 3. Pandas实现需求过程详解 3.1 碎碎 ...

  5. python 将excel文件转换为txt文件_python利用pandas将excel文件转换为txt文件的方法

    python将数据换为txt的方法有很多,可以用xlrd库实现.本人比较懒,不想按太多用的少的插件,利用已有库pandas将excel文件转换为txt文件. 直接上代码: ''' function:将 ...

  6. 编辑器未包含main类型_利用 ONLYOFFICE 将在线文档编辑器集成到 Python Web 应用程序中...

    通过 API,开发人员可以将 ONLYOFFICE 编辑器集成到网站和利用程序设计语言编写的应用程序中,并能配置和管理编辑器. 来源:https://linux.cn/article-13037-1. ...

  7. c语言读取excel表格_利用pandas处理excel表格

    这不是一篇详细介绍pandas的文章,只是我在利用python处理excel表格时找到的一些临时方案,为了避免忘记,记录在这里,也可能对你有帮助. pandas在对excel处理上使用的是xlrd和x ...

  8. python excel文件转换成字符串_python利用pandas将excel文件转换为txt文件的方法

    python将数据换为txt的方法有很多,可以用xlrd库实现.本人比较懒,不想按太多用的少的插件,利用已有库pandas将excel文件转换为txt文件. 直接上代码: ''' function:将 ...

  9. python在excel中的应用-Python利用pandas处理Excel数据的应用详解

    最近迷上了高效处理数据的pandas,其实这个是用来做数据分析的,如果你是做大数据分析和测试的,那么这个是非常的有用的!!但是其实我们平时在做自动化测试的时候,如果涉及到数据的读取和存储,那么而利用p ...

最新文章

  1. 统计的一个小题目python实现
  2. 基于SharePoint 2013的论坛解决方案[开源]
  3. androidstudio环境配置常见问题解决
  4. 陷阱计算机音乐谱大全,陷阱 原版C调-王北车-和弦谱-《弹吧》官网tan8.com-和弦谱大全,学吉他,秀吉他...
  5. mysql 工具 08s01_Mysql管理必备工具Maatkit详解之十四(mk-kill)
  6. 收藏 | 超轻量目标检测模型NanoDet,比YOLO跑得快,上线两天Star量超200
  7. 网络存储SAN网络存储术语解释
  8. 如何使用 Numbers 筛选出特定种类的资料?
  9. 安装idea(最新版IntelliJ IDEA)编译器(详细到每步)
  10. 一款轻量级android图表组件SimpleChart-Kotlin
  11. android系统修改开机动画效果,Android手机开机动画的修改
  12. android 8 奕骆,这才是超级手机 奕骆6000mAh称霸全球 USB Type-C
  13. 高估问题以及解决方法
  14. win10打开蓝牙_学会了这些win10快捷键,可以极大的提高你的工作效率
  15. java字符串长度(java字符串长度压缩)
  16. 黑暗之光第2章:角色创建(魔法师和剑士)
  17. web课程设计网页规划与设计:个人毕设网站设计 —— 二手书籍(11个页面) HTML+CSS+JavaScript...
  18. PKI和数字证书基本原理
  19. Z-001 IVD体外诊断液面探测专题
  20. 一个优秀的IT管理员是如何快乐的面对枯燥的日常工作的?

热门文章

  1. 齿轮齿根裂缝故障对铁路机车的振动特性(牵引动力)
  2. Spark join和cogroup算子
  3. 关于Taro3.0如何使用React-Native的Pushy以及android打包
  4. Docker——使用Dockerfile制作java程序镜像
  5. Linux系统安装pycharm教程
  6. 真无线蓝牙耳机性价比排行榜,2022热门蓝牙耳机推荐
  7. 初中学历学前端难不难
  8. js处理字符串、数组的方法
  9. java 调用方法 数组_JAVA方法与数组
  10. grep 正则表达式的使用