openpyxl是读取大xlsx文件最快的库吗?

1 投票
2 回答
4032 浏览
提问于 2025-04-18 07:16

我刚开始学Python,但我正在写一个脚本,使用openpyxl来读取很大的xlsx文件(60000行x187列),然后把这些数据放进Numpy数组里,以便进行一些机器学习。我的代码是:

from openpyxl import load_workbook
import re
from numpy import *

wb = load_workbook(filename = 'dataSheet.xlsx', use_iterators = True) #dataSheet.xlsx
ws1 = wb.get_sheet_by_name(name = 'LogFileData')

startCol = 1 #index from 1
startRow = 2 #start at least from 2 because header is in 1st row
endCol   = ws1.get_highest_column() #index of last used column, from 1
endRow   = ws1.get_highest_row() #index of last used row, indexed from 1
diff     = endRow - startRow + 1 #number of rows in the data array

header   = [] #contains the column labels
data     = zeros((0,endCol), dtype=float64) #2D array that holds the data

#puts the column headers into a list
for row in ws1.get_squared_range(1, 1, endCol, 1): #indexed from 1
    for cell in row:
        for match in re.findall("<(.*?)>", cell.value):
            header.append(match)

#indexed from 1 when using the ws1
#index from 0 when using the Numpy arrays, tempRow, tempPt, data
for index, row in enumerate(ws1.iter_rows(row_offset=1)):
    tempRow = zeros((1,0), dtype=float64)
    tempPt = zeros((1,1), dtype=float64)
    for cell in row:
        value = cell.value
        if isinstance(value, basestring):
            tempPt[0][0] = None
        else:
            tempPt[0][0]=value
        tempRow = hstack((tempRow,tempPt))
    data = vstack((data,tempRow))

请问openpyxl和优化读取器是处理这个问题最快、最节省空间的方法吗?我的同事提到,使用csv文件配合itertools或类似的工具可能会更快。

编辑 1:
我的电脑配置:
Ubuntu 10.04 LTS在VMWare上
Python 2.6.5
Intel i5四核处理器
2.5GHz
Windows 7企业版

2 个回答

-4

读取一个xlsx表格最快的方法。

一个56MB的文件,里面有超过50万行和4个工作表,处理这个文件花了6秒钟。

import zipfile
from bs4 import BeautifulSoup

paths = []
mySheet = 'Sheet Name'
filename = 'xlfile.xlsx'
file = zipfile.ZipFile(filename, "r")

for name in file.namelist():
    if name == 'xl/workbook.xml':
        data = BeautifulSoup(file.read(name), 'html.parser')
        sheets = data.find_all('sheet')
        for sheet in sheets:
            paths.append([sheet.get('name'), 'xl/worksheets/sheet' + str(sheet.get('sheetid')) + '.xml'])

for path in paths:
    if path[0] == mySheet:
        with file.open(path[1]) as reader:
            for row in reader:
                print(row)  ## do what ever you want with your data
        reader.close()

希望你喜欢,祝编程愉快。

3

我在我的2009年款MacBook上测试了优化过的读取器,处理100万个数字单元格大约需要20秒。我觉得你的代码可能会稍微慢一点,因为它在处理单元格时有一些间接操作,还有模式匹配(建议把模式编译放在循环外面),但我认为速度还是可以接受的。当然,如果你能轻松获取CSV格式的数据,那速度会更快。

我很想知道你的测试结果。

撰写回答