Вопрос по python, excel – итерация по диапазону строк с использованием ws.iter_rows в оптимизированном считывателе openpyxl

9

Мне нужно прочитать файл 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   ответа
5

Отдокументация:

Note: When a worksheet is created in memory, it contains no cells. They are created when first accessed. This way we don’t create objects that would never be accessed, thus reducing the memory footprint.

Warning: Because of this feature, scrolling through cells instead of accessing them directly will create them all in memory, even if you don’t assign them a value. Something like

>>> for i in xrange(0,100):
...             for j in xrange(0,100):
...                     ws.cell(row = i, column = j)

will create 100x100 cells in memory, for nothing.

However, there is a way to clean all those unwanted cells, we’ll see that later.

Я думаю, что доступ к свойствам столбцов или строк приведет к загрузке многих ячеек в память. Я бы предложил только попытаться получить прямой доступ к нужным клеткам.

например.

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
19

Самое простое решение с нижней границей было бы что-то вроде этого:

# 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. Этот метод довольно прост и работает с итераторами в отличие от диапазона или среза, и при желании может быть использован только с нижней границей. Ура!

Error: User Rate Limit Exceeded

Похожие вопросы