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通过PIL获取图片主要颜色并和颜色库进行对比的方法
Mar 19 Python
python删除特定文件的方法
Jul 30 Python
Python实现读取txt文件并转换为excel的方法示例
May 17 Python
利用Python如何批量修改数据库执行Sql文件
Jul 29 Python
Python使用numpy产生正态分布随机数的向量或矩阵操作示例
Aug 22 Python
python实现对任意大小图片均匀切割的示例
Dec 05 Python
python2爬取百度贴吧指定关键字和图片代码实例
Aug 14 Python
浅析PyTorch中nn.Module的使用
Aug 18 Python
Python操作Mongodb数据库的方法小结
Sep 10 Python
Python实现线性插值和三次样条插值的示例代码
Nov 13 Python
python实现密码强度校验
Mar 18 Python
python中如何写类
Jun 29 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/10/09 PHP
php URL跳转代码 减少外链
2011/06/25 PHP
关于Iframe如何跨域访问Cookie和Session的解决方法
2013/04/15 PHP
PHP5常用函数列表(分享)
2013/06/07 PHP
php中的Base62类(适用于数值转字符串)
2013/08/12 PHP
PHP利用func_get_args和func_num_args函数实现函数重载实例
2014/11/12 PHP
php中mysql操作buffer用法详解
2015/03/19 PHP
功能强大的PHP图片处理类(水印、透明度、旋转)
2015/10/21 PHP
PHP whois查询类定义与用法示例
2019/04/03 PHP
Javascript技巧之不要用for in语句对数组进行遍历
2010/10/20 Javascript
Jquery 监视按键,按下回车键触发某方法的实现代码
2014/05/11 Javascript
JS动态显示表格上下frame的方法
2015/03/31 Javascript
javascript实现unicode与ASCII相互转换的方法
2015/12/10 Javascript
jQuery动画效果相关方法实例分析
2015/12/31 Javascript
微信小程序  action-sheet详解及实例代码
2016/11/09 Javascript
vue计算属性时v-for处理数组时遇到的一个bug问题
2018/01/21 Javascript
JavaScript canvas绘制折线图
2020/02/18 Javascript
python 网络爬虫初级实现代码
2016/02/27 Python
Python进阶之全面解读高级特性之切片
2019/02/19 Python
python仿抖音表白神器
2019/04/08 Python
python安装requests库的实例代码
2019/06/25 Python
初次部署django+gunicorn+nginx的方法步骤
2019/09/11 Python
使用CSS3滤镜的filter:blur属性制作毛玻璃模糊效果的方法
2016/07/08 HTML / CSS
HTML5中实现拖放效果无须借助javascript
2012/12/26 HTML / CSS
canvas实现圆形进度条动画的示例代码
2017/12/26 HTML / CSS
中国电子产品外贸网站:MiniIntheBox
2017/02/06 全球购物
应届毕业生就业自荐信
2013/10/26 职场文书
中专生职业生涯规划书范文
2014/01/10 职场文书
青春演讲稿范文
2014/05/08 职场文书
机电专业毕业生求职信
2014/07/01 职场文书
肖申克的救赎观后感
2015/06/02 职场文书
python爬取新闻门户网站的示例
2021/04/25 Python
mysql自增长id用完了该怎么办
2022/02/12 MySQL
MySQL 外连接语法之 OUTER JOIN
2022/04/09 MySQL
Oracle 11g数据库使用expdp每周进行数据备份并上传到备份服务器
2022/06/28 Oracle
maven 解包依赖项中的文件的解决方法
2022/07/15 Java/Android