web-dev-qa-db-ja.com

openpyxlの最適化されたリーダーでws.iter_rowsを使用して、行の範囲を反復処理します

10x5324セルのxlsxファイルを読み取る必要があります

これは私がやろうとしていたことの要点です:

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

範囲関数なしでそれを行う方法はありますか?

私はそれを行う1つの方法は次のようになると思います:

for i in ws.iter_rows[1:]:
    if i.row == startrow:
        continue
    print i[col['Time']].value.hour
    if i.row == endrow:
        break

しかし、もっとエレガントな解決策はありますか? (それはどちらも機能しません)

10
Ali Haroon

下限のある最も単純な解決策は、次のようになります。

# 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...

インデックス変数は、現在の行のカウントを保持するため、rangeまたはxrangeの代わりに使用できます。この方法は非常に簡単で、範囲やスライスとは異なり、イテレータで機能し、必要に応じて下限だけで使用することもできます。乾杯!

20
mikeybaby173

ドキュメント から:

注:ワークシートがメモリ内に作成される場合、セルは含まれません。それらは最初にアクセスされたときに作成されます。このようにして、決してアクセスされないオブジェクトを作成しないため、メモリフットプリントが削減されます。

警告:この機能により、セルに直接アクセスする代わりにセルをスクロールすると、値を割り当てなくても、すべてのセルがメモリに作成されます。何かのようなもの

>>> 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
5
Dunes