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求解平方根的方法
Mar 11 Python
Python的面向对象编程方式学习笔记
Jul 12 Python
Python实现并行抓取整站40万条房价数据(可更换抓取城市)
Dec 14 Python
Python随机读取文件实现实例
May 25 Python
Python编写一个闹钟功能
Jul 11 Python
用PyInstaller把Python代码打包成单个独立的exe可执行文件
May 26 Python
python3实现基于用户的协同过滤
May 31 Python
python实现自动登录后台管理系统
Oct 18 Python
java判断三位数的实例讲解
Jun 10 Python
python生成大写32位uuid代码
Mar 03 Python
Python celery原理及运行流程解析
Jun 13 Python
Django数据模型中on_delete使用详解
Nov 30 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
如何在WIN2K下安装PHP4.04
2006/10/09 PHP
php strnatcmp()函数的用法总结
2013/11/27 PHP
PHP下的Oracle客户端扩展(OCI8)安装教程
2014/09/10 PHP
php提取身份证号码中的生日日期以及验证是否为成年人的函数
2015/09/29 PHP
PHP实现查询手机归属地的方法详解
2017/04/28 PHP
php获取是星期几的的一些常用姿势
2019/12/15 PHP
javascript中的array数组使用技巧
2010/01/31 Javascript
利用JQuery制作符合Web标准的QQ弹出消息
2014/01/14 Javascript
js,jquery滚动/跳转页面到指定位置的实现思路
2014/06/03 Javascript
JS通过ajax动态读取xml文件内容的方法
2015/03/24 Javascript
jquery实现select选择框内容左右移动代码分享
2015/11/21 Javascript
jQuery Timelinr实现垂直水平时间轴插件(附源码下载)
2016/02/16 Javascript
JS组件Bootstrap Table使用实例分享
2016/05/30 Javascript
使用递归遍历对象获得value值的实现方法
2016/06/14 Javascript
JavaScript中boolean类型之三种情景实例代码
2016/11/21 Javascript
js获取当前周、上一周、下一周日期
2017/03/19 Javascript
node.js中ws模块创建服务端和客户端,网页WebSocket客户端
2019/03/06 Javascript
微信小程序生成二维码的示例代码
2019/03/29 Javascript
layui时间控件选择时间范围的实现方法
2019/09/28 Javascript
[06:45]DOTA2-DPC中国联赛 正赛 Magma vs LBZS 选手采访
2021/03/11 DOTA
python基础while循环及if判断的实例讲解
2017/08/25 Python
python爬取微信公众号文章的方法
2019/02/26 Python
详解python中的数据类型和控制流
2019/08/08 Python
对Pytorch神经网络初始化kaiming分布详解
2019/08/18 Python
Selenium使用Chrome模拟手机浏览器方法解析
2020/04/10 Python
Pyinstaller 打包发布经验总结
2020/06/02 Python
Keras实现DenseNet结构操作
2020/07/06 Python
Python中三维坐标空间绘制的实现
2020/09/22 Python
提高python代码运行效率的一些建议
2020/09/29 Python
python unichr函数知识点总结
2020/12/16 Python
CSS3实现文本垂直排列的方法
2018/07/10 HTML / CSS
土木工程应届生自荐信
2013/09/24 职场文书
新闻编辑自荐信
2013/11/03 职场文书
美容院经理岗位职责
2014/04/03 职场文书
科学育儿宣传标语
2014/10/08 职场文书
祝酒词范文
2015/08/12 职场文书