2012-05-16 7 views
9

ho bisogno di leggere un file xlsx di 10x5324 celluleiterazione in un intervallo di righe utilizzando ws.iter_rows nel lettore ottimizzata di openpyxl

Questa è l'essenza di quello che stavo cercando di fare:

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 

Il codice impiegava troppo tempo per essere eseguito, quindi (dovevo eseguire operazioni, non stampare) e dopo un po 'sono diventato impaziente e l'ho annullato.

Qualche idea su come posso lavorarlo nel lettore ottimizzato? Ho bisogno di scorrere su un intervallo di righe, non su tutte le righe. Questo è quello che ho provato, ma è sbagliato:

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 

C'è un modo per farlo senza la funzione di gamma?

immagino un modo per farlo sarebbe:

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

, ma c'è una soluzione più elegante? (che non funziona neanche btw)

risposta

5

Dal documentation:

Nota: Quando un foglio di lavoro viene creata in memoria, non contiene cellule. Essi vengono creati al primo accesso. In questo modo non creiamo oggetti a cui non è mai consentito l'accesso a , riducendo così il footprint di memoria.

Avvertenza: Grazie a questa funzione, lo scorrimento delle celle anziché l'accesso diretto a li creerà tutti in memoria, anche se non si assegna un valore a . Qualcosa come

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

creerà 100 x 100 celle in memoria, per niente.

Tuttavia, c'è un modo per pulire tutte quelle celle indesiderate, vedremo più avanti lo .

Penso che l'accesso alle proprietà di colonne o righe causerà il caricamento di molte celle in memoria. Suggerirei solo di provare ad accedere direttamente alle celle di cui hai bisogno.

es.

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 
18

La soluzione più semplice, con un limite inferiore potrebbe essere qualcosa di simile:

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

Ecco un altro modo per eseguire ciò che si descrive, con la funzione 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... 

L'indice variabile tiene conto di quale riga sei, quindi può essere usata al posto di intervallo o xrange. Questo metodo è piuttosto semplice e funziona con gli iteratori a differenza della gamma o dell'affettatura e, se lo si desidera, può essere utilizzato anche con il limite inferiore. Saluti!

+1

da aggiungere alla soluzione 2 - è possibile aggiungere un'altra istruzione per uscire dal for, per interrompere l'iterazione su tutte le righe una volta che è passato –

Problemi correlati