我尝试编写一个Python-3函数,将xlsx文件中的数字数据读取到numpy数组中。我通常只想从特定的工作表中读取特定的区域。这些区域可能很小(十几个单元格),也可能很大(很容易达到5000 x 10000)。我对文本几乎不感兴趣,对函数、图形和格式一点也不感兴趣。到目前为止,我的方法如下(我编写的代码仅由我自己使用,因此我不遵循一些/许多约定和政治公众人物):
def xlsreadOnly(file, rangeName, sheet = 'Sheet1', dataOnly = True, forceNum = False):
from openpyxl import load_workbook
from openpyxl.utils.cell import coordinate_from_string, column_index_from_string
from numpy import empty, nan
import io
with open(file, 'rb') as f:
in_mem_file = io.BytesIO(f.read())
wb = load_workbook(filename = in_mem_file, read_only = True, data_only = dataOnly)
ws = wb[sheet]
# find the indeces of left-upper and right-lower cells
areal = rangeName
w = areal.find(":")
lu = coordinate_from_string(areal[0:w])
luR = lu[1]
luC = column_index_from_string(lu[0])
rl = coordinate_from_string(areal[w+1:])
rlR = rl[1]
rlC = column_index_from_string(rl[0])
# initialize variable raw
raw = empty([rlR-luR+1, rlC-luC+1], dtype = 'object')
ctor = 0
# iterate over the rows from left-upper to right-lower cell
for row in ws.iter_rows(min_row=luR, max_row=rlR, min_col=luC, max_col=rlC, values_only=True):
raw[ctor, :] = np.array(row)
ctor += 1
return raw
我使用了in_mem_file
,因为它在早期版本中稍微加快了函数的速度。工作簿以read_only
的形式加载,感兴趣的区域以左上行(luR
)、右下行(lrR
)的形式逐段可用。变量raw
预先以适当的大小初始化,因此不存在append
有趣的部分似乎是循环
for row in ws.iter_rows(min_row=luR, max_row=rlR, min_col=luC, max_col=rlC, values_only=True):
我读到的工作表大小为2535 x 4763。如果我读取一个大小为100 x 4763的区域,该功能需要大约4.2秒(i5-9600,3.7GHz,16GB RAM,SSD),这听起来对我来说太长了。如果我将面积减少到100x3,仍然需要4.0秒(是的,对于300个单元!)。看起来,列的数量实际上是无关紧要的。但是,时间几乎与行数成线性关系,因此将面积增加到500 x 4763大约需要22秒。读取整个文件需要相应的时间
在raw[ctor, :] = np.array(row)
中删除到numpy数组的转换几乎不会增加计算时间
我真的认为我错过了一些非常明显的东西,但在搜索了几天之后,我仍然没有看到它!绝望而真诚地感谢你把我的头指向我的错误
编辑:@Charlie Clark,你的评论是100%真实的,代码不太容易阅读,并且有一些不必要的代码。我做了一些改变,希望现在更好。我还根据需要更新了文本。我忘了提到从一个小工作表中读取相同的100x3区域只需几毫秒。因此,问题似乎出在(我对for循环的理解)中
目前没有回答
相关问题 更多 >
编程相关推荐