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 相关文章推荐
python3读取MySQL-Front的MYSQL密码
May 03 Python
Python中顺序表的实现简单代码分享
Jan 09 Python
python的内存管理和垃圾回收机制详解
May 18 Python
十行代码使用Python写一个USB病毒
Jun 21 Python
Pandas之DataFrame对象的列和索引之间的转化
Jun 25 Python
Python中filter与lambda的结合使用详解
Dec 24 Python
python 实现两个线程交替执行
May 02 Python
解决python执行较大excel文件openpyxl慢问题
May 15 Python
Python过滤掉numpy.array中非nan数据实例
Jun 08 Python
python 判断一组数据是否符合正态分布
Sep 23 Python
浅谈Selenium 控制浏览器的常用方法
Dec 04 Python
python中子类与父类的关系基础知识点
Feb 02 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
怎样辨别一杯好咖啡
2021/03/03 新手入门
解决phpmyadmin中文乱码问题。。。
2007/01/18 PHP
php实现统计邮件大小的方法
2013/08/06 PHP
php购物车实现方法
2015/01/03 PHP
PHP抽奖算法程序代码分享
2015/10/08 PHP
javascript 判断数组是否已包含了某个元素的函数
2010/05/30 Javascript
简单选项卡 js和jquery制作方法分享
2014/02/26 Javascript
javascript检查浏览器是否已经启用XX功能
2015/07/10 Javascript
JQuery中ajax方法访问web服务实例
2015/07/18 Javascript
如何用angularjs制作一个完整的表格
2016/01/21 Javascript
jQuery弹出div层过2秒自动消失
2016/11/29 Javascript
JavaScript继承与多继承实例分析
2018/05/26 Javascript
bootstrap下拉框动态赋值方法
2018/08/10 Javascript
Vue Cli 3项目使用融云IM实现聊天功能的方法
2019/04/19 Javascript
如何基于原生javaScript生成带图片的二维码
2019/11/21 Javascript
JS实现购物车基本功能
2020/11/08 Javascript
[07:25]DOTA2-DPC中国联赛2月5日Recap集锦
2021/03/11 DOTA
在Django中创建第一个静态视图
2015/07/15 Python
Python创建二维数组实例(关于list的一个小坑)
2017/11/07 Python
python实现kMeans算法
2017/12/21 Python
Python读取mat文件,并转为csv文件的实例
2018/07/04 Python
对Python3 pyc 文件的使用详解
2019/02/16 Python
详解Python中的正斜杠与反斜杠
2019/08/09 Python
Python3.7安装pyaudio教程解析
2020/07/24 Python
python 操作excel表格的方法
2020/12/05 Python
python基于win32api实现键盘输入
2020/12/09 Python
HTML5 在canvas中绘制文本附效果图
2014/06/23 HTML / CSS
世界上最大的各式箱包网络零售店:eBag
2016/07/21 全球购物
匡威比利时官网:Converse Belgium
2017/04/13 全球购物
俄罗斯建筑和装饰材料在线商店:Stroilandia
2020/07/25 全球购物
荷兰天然和有机产品网上商城:BigGreenSmile.nl
2020/07/26 全球购物
幼儿园教师师德师风演讲稿:爱我所爱 无悔青春
2014/09/10 职场文书
幼儿园小班工作总结2015
2015/04/25 职场文书
音乐剧猫观后感
2015/06/04 职场文书
《童年的发现》教学反思
2016/02/18 职场文书
用golang如何替换某个文件中的字符串
2021/04/25 Golang