直接上源代码:

#!/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. databinding学习(1)
  2. 数据中台(二)数据质量分析及提升
  3. 学生党如何拿到阿里技术offer:《阿里面试(成功)》
  4. java循环链表类_3、循环链表(java实现)
  5. 【Linux系统编程】线程堆栈大小的使用介绍
  6. 电信信息日志使用mapreduce统计的两种方式
  7. iOS制作一个雷达图,可用于多种场景(一)
  8. ubuntu18.04安装opencv4.3.0
  9. 关于对知识的系统建立和站在更高层次进行理解的必要性
  10. UISC-User Interface States Control ;Murphy 用户界面状态控制(Beta)
  11. 你所不知道的Quartz特性
  12. 网络工程师常见面试题,1分钟就能看完
  13. 用protues作RC桥式振荡电路仿真,无法形成正弦波,求解惑
  14. unity材质球发光_为Unity3D创建素材(1):图片、着色器、材质球
  15. 模块化认知:演化如何自下而上涌现出智能?
  16. CSP-M2 B - HRZ 学英语
  17. 2014年4月微软MVP当选名单揭晓!
  18. 怎么恢复相机格式化的照片?
  19. Spring boot + netty开发即时通讯 IM
  20. 古文摘抄(持续不定时更新)

热门文章

  1. 取消html里字体自带的行间距
  2. 微信朋友圈推广广告怎么投放?
  3. OrangePi_Zero2 引脚图
  4. 推动 物联网智慧城市关键
  5. JAVA+SQL实训报告--工资管理系统(详细)
  6. Java开发微信小程序授权登录
  7. python缺省函数写法
  8. java动态生成ppt字体设置
  9. [数据分析与可视化] Python绘制数据地图1-GeoPandas入门指北
  10. linux下开放sftp端口,在Linux系统中更改默认的SFTP端口及使用新的SFTP端口