Итерация по диапазону строк с использованием ws.iter_rows в оптимизированном считывателе openpyxl
Мне нужно прочитать файл xlsx 10x5324 ячеек
Это суть того, что я пытался сделать:
from openpyxl import load_workbook
filename = 'file_path'
wb = load_workbook(filename)
ws = wb.get_sheet_by_name('LOG')
col = {'Time':0 ...}
for i in ws.columns[col['Time']][1:]:
print i.value.hour
Выполнение кода заняло слишком много времени, а затем (я выполнял операции, а не печать), и через некоторое время я потерял терпение и отменил его.
Любая идея, как я могу работать в оптимизированном читателе? Мне нужно перебрать диапазон строк, а не все строки. Это то, что я пытался, но это неправильно:
wb = load_workbook(filename, use_iterators = True)
ws = wb.get_sheet_by_name('LOG')
for i in ws.iter_rows[1:]:
print i[col['Time']].value.hour
Есть ли способ сделать это без функции дальности?
Я думаю, один из способов сделать это будет:
for i in ws.iter_rows[1:]:
if i.row == startrow:
continue
print i[col['Time']].value.hour
if i.row == endrow:
break
но есть ли более элегантное решение? (это тоже не работает)
2 ответа
Самое простое решение с нижней границей было бы что-то вроде этого:
# Your code:
from openpyxl import load_workbook
filename = 'file_path'
wb = load_workbook(filename, use_iterators=True)
ws = wb.get_sheet_by_name('LOG')
# Solution 1:
for row in ws.iter_rows(row_offset=1):
# code to execute per row...
Вот еще один способ выполнить то, что вы описываете, с enumerate
функция:
# Solution 2:
start, stop = 1, 100 # This will allow you to set a lower and upper limit
for index, row in enumerate(ws.iter_rows()):
if start < index < stop:
# code to execute per row...
Переменная index хранит счет того, в какой строке вы находитесь, поэтому ее можно использовать вместо range или xrange. Этот метод довольно прост и работает с итераторами в отличие от диапазона или среза, и при желании может быть использован только с нижней границей. Ура!
Из документации:
Примечание. Когда лист создается в памяти, он не содержит ячеек. Они создаются при первом обращении. Таким образом, мы не создаем объекты, к которым никогда не будет доступа, тем самым уменьшая объем памяти.
Предупреждение: благодаря этой функции прокрутка ячеек вместо прямого доступа к ним создаст их все в памяти, даже если вы не назначите им значение. Что-то вроде
>>> for i in xrange(0,100): ... for j in xrange(0,100): ... ws.cell(row = i, column = j)
создаст 100x100 ячеек в памяти, даром.
Однако есть способ очистить все эти ненужные клетки, мы увидим это позже.
Я думаю, что доступ к свойствам столбцов или строк приведет к загрузке многих ячеек в память. Я бы предложил только попытаться получить прямой доступ к нужным клеткам.
например.
col_name = 'A'
start_row = 1
end_row = 99
range_expr = "{col}{start_row}:{col}{end_row}".format(
col=col_name, start_row=start_row, end_row=end_row)
for (time_cell,) in ws.iter_rows(range_string=range_expr):
print time_cell.value.hour