python之DataFrame实现excel合并单元格


Posted in Python onFebruary 22, 2021

在工作中经常遇到需要将数据输出到excel,且需要对其中一些单元格进行合并,比如如下表表格,需要根据A列的值,合并B、C列的对应单元格

python之DataFrame实现excel合并单元格

pandas中的to_excel方法只能对索引进行合并,而xlsxwriter中,虽然提供有merge_range方法,但是这只是一个和基础的方法,每次都需要编写繁琐的测试才能最终调好,而且不能很好的重用。所以想自己写一个方法,结合dataframe和merge_range。大概思路是:

1、定义一个MY_DataFrame类,继承DataFrame类,这样能很好的利用pandas的很多特性,而不用自己重新组织数据结构。
2、定义一个my_mergewr_excel方法,参数分别为:输出excel的路径、用于判断是否需要合并的key_cols列表、用于指明哪些列上的单元格需要被合并的列表
3、将MY_DataFrame封装为一个My_Module模块,以备重用。

合并的算法如下:

1、根据给定参数的【关键列】,进行分组计数和排序,添加CN和RN两个辅助列
2、判断CN大于1的,该分组需要合并,否则该分组(行)无需合并(CN=1说明这个分组数据行是唯一的,无需合并)
3、对应需要合并的分组,判断当前列是不是在给定参数【合并列】中,是则用合并写excel单元格,否则就是普通的写excel单元格。
4、在需要合并的列中,如果对于的RN=1则调用merge_range,一次性写想下写CN个单元格,如果RN>1则跳过该单元格,因为在RN=1的时候,已经合并写了该单元格,若再重复调用erge_range,打开excel文档时会报错。

用图解释如下:

python之DataFrame实现excel合并单元格

具体代码如下:

# -*- coding: utf-8 -*- 
""" 
Created on 20170301 
 
@author: ARK-Z 
""" 
import xlsxwriter 
 
 
import pandas as pd 
 
class My_DataFrame(pd.DataFrame): 
 def __init__(self, data=None, index=None, columns=None, dtype=None, copy=False): 
  pd.DataFrame.__init__(self, data, index, columns, dtype, copy) 
 
 def my_mergewr_excel(self,path,key_cols=[],merge_cols=[]): 
  # sheet_name='Sheet1', na_rep='', float_format=None, columns=None, header=True, index=True, index_label=None, startrow=0, startcol=0, engine=None, merge_cells=True, encoding=None, inf_rep='inf', verbose=True): 
  self_copy=My_DataFrame(self,copy=True) 
  line_cn=self_copy.index.size 
  cols=list(self_copy.columns.values) 
  if all([v in cols for i,v in enumerate(key_cols)])==False:  #校验key_cols中各元素 是否都包含与对象的列 
   print("key_cols is not completely include object's columns") 
   return False 
  if all([v in cols for i,v in enumerate(merge_cols)])==False: #校验merge_cols中各元素 是否都包含与对象的列 
   print("merge_cols is not completely include object's columns") 
   return False  
 
  wb2007 = xlsxwriter.Workbook(path) 
  worksheet2007 = wb2007.add_worksheet() 
  format_top = wb2007.add_format({'border':1,'bold':True,'text_wrap':True}) 
  format_other = wb2007.add_format({'border':1,'valign':'vcenter'}) 
  for i,value in enumerate(cols): #写表头 
   #print(value) 
   worksheet2007.write(0,i,value,format_top) 
   
  #merge_cols=['B','A','C'] 
  #key_cols=['A','B'] 
  if key_cols ==[]: #如果key_cols 参数不传值,则无需合并 
   self_copy['RN']=1 
   self_copy['CN']=1 
  else: 
   self_copy['RN']=self_copy.groupby(key_cols,as_index=False).rank(method='first').ix[:,0] #以key_cols作为是否合并的依据 
   self_copy['CN']=self_copy.groupby(key_cols,as_index=False).rank(method='max').ix[:,0] 
  #print(self) 
  for i in range(line_cn): 
   if self_copy.ix[i,'CN']>1: 
    #print('该行有需要合并的单元格') 
    for j,col in enumerate(cols): 
     #print(self_copy.ix[i,col]) 
     if col in (merge_cols): #哪些列需要合并 
      if self_copy.ix[i,'RN']==1: #合并写第一个单元格,下一个第一个将不再写 
       worksheet2007.merge_range(i+1,j,i+int(self_copy.ix[i,'CN']),j, self_copy.ix[i,col],format_other) ##合并单元格,根据LINE_SET[7]判断需要合并几个 
       #worksheet2007.write(i+1,j,df.ix[i,col]) 
      else: 
       pass 
      #worksheet2007.write(i+1,j,df.ix[i,j]) 
     else: 
      worksheet2007.write(i+1,j,self_copy.ix[i,col],format_other) 
     #print(',') 
   else: 
    #print('该行无需要合并的单元格') 
    for j,col in enumerate(cols): 
     #print(df.ix[i,col]) 
     worksheet2007.write(i+1,j,self_copy.ix[i,col],format_other) 
     
     
  wb2007.close() 
  self_copy.drop('CN', axis=1) 
  self_copy.drop('RN', axis=1)

调用代码:

import My_Module 
 
DF=My_DataFrame({'A':[1,2,2,2,3,3],'B':[1,1,1,1,1,1],'C':[1,1,1,1,1,1],'D':[1,1,1,1,1,1]}) 
 
DF 
Out[120]: 
 A B C D 
0 1 1 1 1 
1 2 1 1 1 
2 2 1 1 1 
3 2 1 1 1 
4 3 1 1 1 
5 3 1 1 1 

DF.my_mergewr_excel('000_2.xlsx',['A'],['B','C'])

效果如下:

python之DataFrame实现excel合并单元格

也可以设置合并A、B列:

DF.my_mergewr_excel('000_2.xlsx',['A'],['A','B'])

效果如下:

python之DataFrame实现excel合并单元格

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
简单的Python抓taobao图片爬虫
Oct 26 Python
Python兔子毒药问题实例分析
Mar 05 Python
python获取本地计算机名字的方法
Apr 29 Python
Python实现二叉树结构与进行二叉树遍历的方法详解
May 24 Python
梯度下降法介绍及利用Python实现的方法示例
Jul 12 Python
Python编程图形库之Pillow使用方法讲解
Dec 28 Python
Pycharm新手教程(只需要看这篇就够了)
Jun 18 Python
Python 利用高德地图api实现经纬度与地址的批量转换
Aug 14 Python
详解使用django-mama-cas快速搭建CAS服务的实现
Oct 30 Python
python模块如何查看
Jun 16 Python
keras分类之二分类实例(Cat and dog)
Jul 09 Python
python实现将中文日期转换为数字日期
Jul 14 Python
python合并同类型excel表格的方法
Apr 01 #Python
python实现两个文件合并功能
Apr 01 #Python
Python中一行和多行import模块问题
Apr 01 #Python
Python对List中的元素排序的方法
Apr 01 #Python
Python去除、替换字符串空格的处理方法
Apr 01 #Python
利用scrapy将爬到的数据保存到mysql(防止重复)
Mar 31 #Python
python 通过xml获取测试节点和属性的实例
Mar 31 #Python
You might like
删除无限级目录与文件代码共享
2006/07/12 PHP
php中define用法实例
2015/07/30 PHP
Thinkphp5结合layer弹窗定制操作结果页面
2017/07/07 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
2017/08/17 PHP
JavaScript对象模型-执行模型
2008/04/28 Javascript
理解JavaScript变量作用域更轻松
2009/10/25 Javascript
Node.js的特点和应用场景介绍
2014/11/04 Javascript
JavaScript的Backbone.js框架的一些使用建议整理
2016/02/14 Javascript
BootStrap 超链接变按钮的实现方法
2016/09/25 Javascript
简单实现jQuery级联菜单
2017/01/09 Javascript
nodejs 终端打印进度条实例代码
2017/04/22 NodeJs
详解vue-router 2.0 常用基础知识点之router.push()
2017/05/10 Javascript
浅谈vue中数据双向绑定的实现原理
2017/09/14 Javascript
微信小程序scroll-x失效的完美解决方法
2018/07/18 Javascript
JavaScript实现图片上传并预览并提交ajax
2019/09/30 Javascript
js 计数排序的实现示例(升级版)
2020/01/12 Javascript
javascript异常处理实现原理详解
2020/02/17 Javascript
JavaScript实现捕获鼠标坐标
2020/04/12 Javascript
js实现筛选功能
2020/11/24 Javascript
antdesign-vue结合sortablejs实现两个table相互拖拽排序功能
2021/01/08 Vue.js
python基础教程之udp端口扫描
2014/02/10 Python
python益智游戏计算汉诺塔问题示例
2014/03/05 Python
由Python运算π的值深入Python中科学计算的实现
2015/04/17 Python
Python运算符重载用法实例
2015/05/28 Python
轻松理解Python 中的 descriptor
2017/09/15 Python
python读取图片的方式,以及将图片以三维数组的形式输出方法
2019/07/03 Python
python+selenium 脚本实现每天自动登记的思路详解
2020/03/11 Python
PyTorch之nn.ReLU与F.ReLU的区别介绍
2020/06/27 Python
英国顶级水晶珠宝零售商之一:Tresor Paris
2019/04/27 全球购物
德国家具、照明、家居用品网上商店:Wayfair.de
2020/02/13 全球购物
拖鞋店创业计划书
2014/01/15 职场文书
幼儿园教师自我鉴定
2014/03/20 职场文书
最美家庭活动方案
2014/08/31 职场文书
2014学习优秀共产党员先进事迹材料思想汇报
2014/09/14 职场文书
面试自我评价范文
2014/09/17 职场文书
python读取并查看npz/npy文件数据以及数据显示方法
2022/04/14 Python