免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 8210 | 回复: 10
打印 上一主题 下一主题

python操作excel性能问题求助 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-09-28 00:38 |只看该作者 |倒序浏览
我刚刚用python写了一段操作excel的脚本,目的是把一个excel文件按照某一列中的字段拆分成多个文件,例如按照城市或者省份等,但是发现处理一个1700行的文件拆分成40多个文件时要运行30分钟左右,性能太慢,请高手帮忙看看怎么才能优化性能,谢谢。

新手写的脚本,请不要见笑,如下:

'''
Created on 2009-9-25

@author: vidon
'
''
#_*_ coding:UTF-8 _*_

import os, sys, time
import win32com.client
xls=win32com.client.Dispatch("Excel.Application")
xls.Visible=False

source_path = input('请输入要操作的文件名路径与名称(例如:D:\ABC\BOOK.XLS):').replace('\r','')
target_path = input('请输入存放数据处理结果的目录(例如:D:\BACK\):').replace('\r','')
x=int(input("请输入表头的行数:").replace('\r',''))
y=int(input("请输入作为拆分数据的依据所在列的号码:").replace('\r',''))

if not os.path.exists(target_path):
    os.mkdir(target_path)
    print("已经创建指定的目录,准备创建文件,请稍等······")
else:
    print("准备创建文件,请稍等······")
    
#读取原始文件
book=xls.Workbooks.Open(source_path)
sheet=book.ActiveSheet
length = sheet.UsedRange.Rows.Count
y_length = sheet.UsedRange.Columns.Count
keyArray = []
for i in range((x+1),length):
    keyArray.append(sheet.Cells(i,y).Value)
   
#根据指定的列中的字段创建新文件
ll = len(keyArray)
for j in range(1,ll):
    
    filename = target_path + str(keyArray[j]) + ".xls"
    if os.path.exists (filename):
        continue
    else :
        sheet.Range(sheet.Cells(1,1),sheet.Cells(x,y_length)).select
        sheet.Range(sheet.Cells(1,1),sheet.Cells(x,y_length)).copy
        newbook = xls.Workbooks.Add()
        newsheet=newbook.ActiveSheet
        newsheet.Range(newsheet.Cells(1,1),newsheet.Cells(x,y_length)).select
        newsheet.Paste()
        newbook.SaveAs(filename)
        print ("成功创建文件:",filename)
        newbook.close
 
#拷贝符合条件的记录到指定的文件
print("正在处理数据,请稍等······")
for i in range((x+1),length) :
    address = sheet.Cells(i,y).value
    address_xls = xls.Workbooks.Open(target_path + address +".xls")
    address_sheet = xls.ActiveSheet
    sheet = book.ActiveSheet
    sheet.Range(sheet.Cells(i,1),sheet.Cells(i,y_length)).copy
    address_length = address_sheet.UsedRange.Rows.Count
    address_sheet.Range(address_sheet.Cells(address_length+1,1),address_sheet.Cells(address_length+1,y_length)).select
    address_sheet.Paste()
    address_xls.Save()
    address_xls.close

book.close
xls.quit
print ("恭喜!数据处理完毕!")

论坛徽章:
0
2 [报告]
发表于 2009-09-28 08:06 |只看该作者
找点profile之类的工具试试看哪儿比较耗时间

论坛徽章:
0
3 [报告]
发表于 2009-09-28 08:41 |只看该作者
我通过跟踪测试已经发现就是下面这部分选择/复制/粘贴数据以及保存文件这一块耗时,但是我不知道怎么改才能提升性能。

请帮忙看看这段代码有没有改进的方法?

谢谢!

#拷贝符合条件的记录到指定的文件
print("正在处理数据,请稍等······")
for i in range((x+1),length) :
    address = sheet.Cells(i,y).value
    address_xls = xls.Workbooks.Open(target_path + address +".xls")
    address_sheet = xls.ActiveSheet
    sheet = book.ActiveSheet
    sheet.Range(sheet.Cells(i,1),sheet.Cells(i,y_length)).copy
    address_length = address_sheet.UsedRange.Rows.Count
    address_sheet.Range(address_sheet.Cells(address_length+1,1),address_sheet.Cells(address_length+1,y_length)).select
    address_sheet.Paste()
    address_xls.Save()
    address_xls.close

论坛徽章:
0
4 [报告]
发表于 2009-09-28 10:48 |只看该作者
找找xlrd之类的模块进行excel的处理吧。

论坛徽章:
0
5 [报告]
发表于 2009-09-28 12:49 |只看该作者
谢谢limodou老大的建议,我当初在网上查询就是看到有com、xlrd和pyExcelerator三种方式可以选择,看介绍说xlrd与pyExcelerator两者一个注重读一个注重写,而且网上没有发现有完整的教程,后来选择了com方式操作。

能帮忙介绍一下这三者到底各有哪些优势与缺点吗?

谢谢!

我是一个新手,工作也不是编程,写这个脚本的目的一个是为了解决工作中的实际问题,另一个目的就是想借助解决问题的过程学习一下python,为以后能够更方便的解决工作中的一些小问题。

论坛徽章:
0
6 [报告]
发表于 2009-09-28 13:29 |只看该作者
后两个我记得是不需要通过com方式,是直接读取文件的,所以速度要快很多。xlrd我用过,还可以比较简单,它的代码有例子,可以看看就能写了。

论坛徽章:
0
7 [报告]
发表于 2009-09-28 13:47 |只看该作者
还有一个模块xlwt用来做excel写操作, 好像是从pyex...继承过来的。
不过直接读写excel文件,而不经过com的话,有可能会丢失一些文件信息,比如复杂的宏定义等等, 用的时候需要小心。
原帖由 limodou 于 2009-9-28 13:29 发表
后两个我记得是不需要通过com方式,是直接读取文件的,所以速度要快很多。xlrd我用过,还可以比较简单,它的代码有例子,可以看看就能写了。

论坛徽章:
0
8 [报告]
发表于 2009-09-28 17:02 |只看该作者
谢谢各位的热心,我回头看一下这些资料,多一种解决途径总是好的。

不过目前这个脚本已经实现到目前这个地步还是想改进一下,总不能遇到困难就绕开吧。

论坛徽章:
0
9 [报告]
发表于 2009-09-28 17:11 |只看该作者
谢谢各位的热心,我回头看一下这些资料,多一种解决途径总是好的。

不过目前这个脚本已经实现到目前这个地步还是想改进一下,总不能遇到困难就绕开吧。

晕,刚才看了一下xlrd,目前还是只支持到2.5.4,我用的3.1,看来还得回到2.5

论坛徽章:
0
10 [报告]
发表于 2009-09-29 09:23 |只看该作者
3.1啊。现在用的人还不多啊。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP