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标准库sched模块使用指南
Jul 06 Python
用Django实现一个可运行的区块链应用
Mar 08 Python
使用pandas对矢量化数据进行替换处理的方法
Apr 11 Python
TensorFlow 滑动平均的示例代码
Jun 19 Python
Python pygorithm模块用法示例【常见算法测试】
Aug 16 Python
python3实现zabbix告警推送钉钉的示例
Feb 20 Python
使用Flask-Cache缓存实现给Flask提速的方法详解
Jun 11 Python
Python列表list常用内建函数实例小结
Oct 22 Python
Python FTP文件定时自动下载实现过程解析
Nov 12 Python
python-sys.stdout作为默认函数参数的实现
Feb 21 Python
Python+OpenCV图像处理—— 色彩空间转换
Oct 22 Python
python爬虫多次请求超时的几种重试方法(6种)
Dec 01 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
PHP中的日期及时间
2006/11/23 PHP
让PHP以ROOT权限执行系统命令的方法
2011/02/10 PHP
Yii操作数据库的3种方法
2014/03/11 PHP
XRegExp 0.2: Now With Named Capture
2007/11/30 Javascript
一些相见恨晚的 JavaScript 技巧
2010/04/25 Javascript
JavaScript Math.ceil 方法(对数值向上取整)
2015/01/09 Javascript
nodejs批量修改文件编码格式
2015/01/22 NodeJs
javascript实现自动输出文本(打字特效)
2015/08/27 Javascript
jQuery实现选中弹出窗口选择框内容后赋值给文本框的方法
2015/11/23 Javascript
jQuery实现底部浮动窗口效果
2016/09/07 Javascript
vue插件vue-resource的使用笔记(小结)
2017/08/04 Javascript
vue + element-ui实现简洁的导入导出功能
2017/12/22 Javascript
Element input树型下拉框的实现代码
2018/12/21 Javascript
Element中的Cascader(级联列表)动态加载省\市\区数据的方法
2019/03/27 Javascript
M2实现Nodejs项目自动部署的方法步骤
2019/05/05 NodeJs
js核心基础之构造函数constructor用法实例分析
2019/05/11 Javascript
Vue 图片压缩并上传至服务器功能
2020/01/15 Javascript
js中延迟加载和预加载的具体使用
2021/01/14 Javascript
[02:59]2014DOTA2西雅图国际邀请赛 圆满落幕中国夺冠
2014/07/23 DOTA
Python中用Ctrl+C终止多线程程序的问题解决
2013/03/30 Python
Python 中的with关键字使用详解
2016/09/11 Python
python 读写txt文件 json文件的实现方法
2016/10/22 Python
Win7下Python与Tensorflow-CPU版开发环境的安装与配置过程
2018/01/04 Python
和孩子一起学习python之变量命名规则
2018/05/27 Python
pyqt5 QProgressBar清空进度条的实例
2019/06/21 Python
python实现高斯判别分析算法的例子
2019/12/09 Python
对Python 字典元素进行删除的方法
2020/07/31 Python
CSS3 Backgrounds属性相关介绍
2011/05/11 HTML / CSS
利用CSS3实现折角效果实例源码
2016/09/28 HTML / CSS
Qoo10台湾站:亚洲领先的在线市场
2018/05/15 全球购物
营销学习心得体会
2014/09/12 职场文书
车辆委托书范本
2014/10/05 职场文书
高校教师个人工作总结2014
2014/12/17 职场文书
2015年维修电工工作总结
2015/04/25 职场文书
创业计划书之香辣虾火锅
2019/09/23 职场文书
PyTorch 实现L2正则化以及Dropout的操作
2021/05/27 Python