我有一个类函数“loadxl()”,它使用openpyxl将数据从Excel读取到Python。我曾试图通过使用“只读”模式和内置迭代器使其速度更快,但我尝试优化函数的速度却只有原始代码的一半
我正在读取的数据是在9241 X 14矩阵中构造的。我正在使用这些数据初始化类“Case”中的变量,这些变量大部分是“numpy”数组
在我的初始代码中,我没有使用“只读”工作簿,而是使用“sheet.cell()”方法访问单元格。这是我的原始代码:
import numpy as np
import openpyxl as opyxl
class Case:
def __init__(
self, filepath = None
):
#Bus data
self.sbase = 500 #Default MVA value
self.numbus = np.empty(0, dtype = np.int32)
self.slackbusnr = []
self.busname = np.empty(0, dtype = np.str)
self.buscod = np.empty(0, dtype = np.int32)
self.basekv = np.empty(0, dtype = np.double)
self.gs = np.empty(0, dtype = np.double)
self.bs = np.empty(0, dtype = np.double)
self.area = np.empty(0, dtype = np.int32)
self.zone = np.empty(0, dtype = np.int32)
self.nbuses = 0
self.vomag = np.empty(0, dtype = np.double)
self.voang = np.empty(0, dtype = np.double)
def loadxl(self,filename):
wb = opyxl.load_workbook(filename)
bus = wb.get_sheet_by_name('Bus-data')
i = 1
while (bus.cell(row = i,column = 1).value is not None):
self.numbus = np.append(self.numbus,int(bus.cell(row = i, column = 1).value))
if(int(bus.cell(row = i, column = 3).value) == 3):
self.slackbusnr = self.nbuses
self.buscod = np.append(self.buscod, int(bus.cell(row = i, column = 4).value))
self.pload = np.append(self.pload, float(bus.cell(row = i, column = 5 ).value)/self.sbase)
self.qload = np.append( self.qload, float(bus.cell(row = i, column = 6).value)/self.sbase)
self.gs = np.append(self.gs, float(bus.cell(row = i, column = 7).value)/self.sbase)
self.bs = np.append(self.bs, float(bus.cell(row = i, column = 8).value)/self.sbase)
self.area = np.append(self.area,int(bus.cell(row = i, column = 9).value))
self.vomag = np.append(self.vomag, float(bus.cell(row = i, column = 10).value))
self.voang = np.append(self.voang, float(bus.cell(row = i, column = 11).value)/180*math.pi)
self.basekv = np.append(self.basekv,float(bus.cell(row = i, column = 12).value))
self.zone = np.append(self.zone,int(bus.cell(row = i, column = 13).value))
self.nbuses += 1
i+=1
原始代码使用大约10秒来读取数据。在阅读了openpyxl的文档和一大堆在线文章之后,我意识到我可以通过加载一个“只读”工作簿来优化代码。但是,.cell()方法在只读模式下速度非常慢,因此我使用了“ws.iter_rows()”而不是while循环。新守则如下:
def loadxl2(filename):
wb = opyxl.load_workbook(filename, read_only = True)
bus = wb.get_sheet_by_name('Bus-data')
for row in bus.iter_rows(min_col = 1, min_row = 1, values_only = True):
if(row[0] == None):
break
self.numbus = np.append(self.numbus,int(row[0]))
self.busname = np.append(self.busname, str(row[1]))
self.buscod = np.append(self.buscod, int(row[2]))
if(int(row[2]) == 3):
self.slackbusnr = self.nbuses
self.pload = np.append(self.pload, float(row[ 3])/self.sbase)
self.qload = np.append( self.qload, float(row[4])/self.sbase)
self.gs = np.append(self.gs, float(row[5])/self.sbase)
self.bs = np.append(self.bs, float(row[6])/self.sbase)
self.area = np.append(self.area,float(row[7]))
self.vomag = np.append(self.vomag, float(row[8]))
self.voang = np.append(self.voang, float(row[9])/180*math.pi)
self.basekv = np.append(self.basekv,float(row[10]))
self.zone = np.append(self.zone,float(row[11]))
self.nbuses += 1
问题是:新代码的速度大约是原代码的一半
我在这两个代码中使用了“line_profile”,发现即使使用“wb.load_工作簿(read_only=True)”加载工作簿也要快得多,新代码中的for循环比while循环慢60倍。(在两个循环中添加数据显示了相同的性能)
openpyxl文档和在线博客/帖子都说,在只读模式下,通过使用内置迭代器读取数据应该更快,那么有人知道我的代码可能有什么问题吗
当你说慢的时候?你说的慢是什么意思?几秒钟、几分钟或几小时
这是Excel的一个小文件,因此时间可能主要取决于加载库。也就是说,每次对相同的列执行相同的操作。让numpy同时对数组中的元素执行所有操作可能是有意义的。毕竟,这是向量运算的要点
我注意到您使用了
self.numbus
,这意味着您使用的是类,我们看不到您的全部代码降低pyautogui速度的一个可靠方法是多次打开工作簿。因此,您可能需要检查工作簿是否只打开一次
另一件事是我看不到什么是
np
。你能添加更多的代码吗既然你在上课,我想知道你是否把所有的东西都装进了内存。这也可能会让它慢一点
我有一个类似的项目,我一列一列地写,这也不是一个好主意。它变得很慢。然后我打开了另一个工作簿来写入数据。基本上是在内存中创建工作簿的副本。然后我写了一次到文件里。 因此,基本上:查看文件写入操作的数量,并减少它
相关问题 更多 >
编程相关推荐