Итерация по диапазону строк с использованием 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
Другие вопросы по тегам