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 相关文章推荐
Django框架中方法的访问和查找
Jul 15 Python
Python入门之三角函数全解【收藏】
Nov 08 Python
Python 用Redis简单实现分布式爬虫的方法
Nov 23 Python
详解tensorflow训练自己的数据集实现CNN图像分类
Feb 07 Python
Python音频操作工具PyAudio上手教程详解
Jun 26 Python
python lambda表达式在sort函数中的使用详解
Aug 28 Python
通过实例学习Python Excel操作
Jan 06 Python
如何基于线程池提升request模块效率
Apr 18 Python
python退出循环的方法
Jun 18 Python
浅谈Python里面None True False之间的区别
Jul 09 Python
Python3读写ini配置文件的示例
Nov 06 Python
Python图像处理之图像拼接
Apr 28 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
smarty+adodb+部分自定义类的php开发模式
2006/12/31 PHP
php 判断是否是中文/英文/数字示例代码
2013/09/30 PHP
php自定义函数截取汉字长度
2014/05/15 PHP
推荐一款MAC OS X 下php集成开发环境mamp
2014/11/08 PHP
laravel 5.3 单用户登录简单实现方法
2019/10/14 PHP
Laravel 验证码认证学习记录小结
2019/12/20 PHP
javaScript NameSpace 简单说明介绍
2013/07/18 Javascript
JS实现遮罩层效果的简单实例
2013/11/12 Javascript
JS 新增Cookie 取cookie值 删除cookie 举例详解
2014/10/10 Javascript
JS动态添加Table的TR,TD实现方法
2015/01/28 Javascript
javascript实现淡蓝色的鼠标拖动选择框实例
2015/05/09 Javascript
node.js入门教程之querystring模块的使用方法
2017/02/27 Javascript
JavaScript实现简单的星星评分效果
2017/05/18 Javascript
vue2.0 中#$emit,$on的使用详解
2017/06/07 Javascript
基于nodejs的微信JS-SDK简单应用实现
2019/05/21 NodeJs
vue-resourc发起异步请求的方法
2020/02/11 Javascript
vue数据更新UI不刷新显示的解决办法
2020/08/06 Javascript
Python内置模块ConfigParser实现配置读写功能的方法
2018/02/12 Python
python构建基础的爬虫教学
2018/12/23 Python
python使用yield压平嵌套字典的超简单方法
2019/11/02 Python
python循环输出三角形图案的例子
2019/11/22 Python
Django生成PDF文档显示网页上以及PDF中文显示乱码的解决方法
2019/12/17 Python
在matplotlib中改变figure的布局和大小实例
2020/04/23 Python
Python 中由 yield 实现异步操作
2020/05/04 Python
HTML5的结构和语义(4):语义性的内联元素
2008/10/17 HTML / CSS
TripAdvisor瑞典:全球领先的旅游网站
2017/12/11 全球购物
音乐专业应届生教师求职信
2013/11/04 职场文书
大学生求职计划书
2014/04/30 职场文书
干部个人考察材料
2014/12/24 职场文书
2015年基层党支部工作总结
2015/05/21 职场文书
运动会广播稿50字
2015/08/19 职场文书
《中彩那天》教学反思
2016/02/24 职场文书
2016年读书月活动总结范文
2016/04/06 职场文书
MySQL 隔离数据列和前缀索引的使用总结
2021/05/14 MySQL
MySQL 覆盖索引的优点
2021/05/19 MySQL
Windows11里微软已经将驱动程序安装位置A盘删除
2021/11/21 数码科技