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实现在matplotlib中两个坐标轴之间画一条直线光标的方法
May 20 Python
Python实现新浪博客备份的方法
Apr 27 Python
在Django同1个页面中的多表单处理详解
Jan 25 Python
python中urllib.unquote乱码的原因与解决方法
Apr 24 Python
Python2.7编程中SQLite3基本操作方法示例
Aug 09 Python
Python使用sort和class实现的多级排序功能示例
Aug 15 Python
在python中画正态分布图像的实例
Jul 08 Python
Python SELENIUM上传文件或图片实现过程
Oct 28 Python
pytorch绘制并显示loss曲线和acc曲线,LeNet5识别图像准确率
Jan 02 Python
Python实现的北京积分落户数据分析示例
Mar 27 Python
Anaconda3中的Jupyter notebook添加目录插件的实现
May 18 Python
Python爬虫中Selenium实现文件上传
Dec 04 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
基于mysql的bbs设计(三)
2006/10/09 PHP
php框架Phpbean说明
2008/01/10 PHP
PHP时间格式控制符对照表分享
2013/07/23 PHP
php封装的验证码类分享
2017/02/26 PHP
PHP操作redis实现的分页列表,新增,删除功能封装类与用法示例
2018/08/04 PHP
CSS和JS标签style属性对照表(方便js开发的朋友)
2010/11/11 Javascript
基于JQuery的类似新浪微博展示信息效果的代码
2012/07/23 Javascript
jQuery插件imgPreviewQs实现上传图片预览
2016/01/15 Javascript
javascript实现随机显示星星特效
2016/01/28 Javascript
实例讲解jQuery EasyUI tree中state属性慎用
2016/04/01 Javascript
js数组的五种迭代方法及两种归并方法(推荐)
2016/06/14 Javascript
AngularJS基础 ng-click 指令示例代码
2016/08/01 Javascript
jQuery简单判断值是否存在于数组中的方法示例
2018/04/17 jQuery
解决mpvue + vuex 开发微信小程序vuex辅助函数mapState、mapGetters不可用问题
2018/08/03 Javascript
详解webpack模块加载器兼打包工具
2018/09/11 Javascript
vue瀑布流组件实现上拉加载更多
2020/03/10 Javascript
利用python程序帮大家清理windows垃圾
2017/01/15 Python
Python 装饰器实现DRY(不重复代码)原则
2018/03/05 Python
对python中list的拷贝与numpy的array的拷贝详解
2019/01/29 Python
对python中if语句的真假判断实例详解
2019/02/18 Python
python实现图片转字符小工具
2019/04/30 Python
Python多版本开发环境管理工具介绍
2019/07/03 Python
python中break、continue 、exit() 、pass终止循环的区别详解
2019/07/08 Python
基于TensorFlow中自定义梯度的2种方式
2020/02/04 Python
简单的Python人脸识别系统
2020/07/14 Python
python 使用三引号时容易犯的小错误
2020/10/21 Python
美国钻石商店:Zales
2016/11/20 全球购物
德国高尔夫商店:Par71.de
2020/11/29 全球购物
Java提供了哪些企业应用编程接口
2015/02/13 面试题
材料加工硕士生求职信
2013/10/10 职场文书
应届行政管理专业个人自我评价
2013/12/28 职场文书
工业学校毕业生自荐信范文
2014/01/03 职场文书
运动会广播稿200字
2014/01/15 职场文书
股权转让意向书
2014/04/01 职场文书
考试作弊检讨书
2015/01/27 职场文书
小学运动会报道稿
2015/07/22 职场文书