iterando en un rango de filas usando ws.iter_rows en el lector optimizado de openpyxl

Necesito leer un archivo xlsx de 10×5324 celdas

Esta es la esencia de lo que estaba tratando de hacer:

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 

El código tardó demasiado en ejecutarse, entonces debería hacerlo (estaba realizando operaciones, no imprimiendo) y después de un tiempo me impacienté y lo cancelé.

¿Alguna idea de cómo puedo trabajar en el lector optimizado? Necesito iterar sobre un rango de filas, no sobre todas las filas. Esto es lo que intenté, pero está mal:

 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 

¿Hay alguna manera de que pueda hacerlo sin la función de rango?

Supongo que una forma de hacerlo sería:

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

¿Pero hay una solución más elegante? (Eso tampoco funciona por cierto)

La solución más simple con un límite inferior sería algo como esto:

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

Aquí hay otra forma de ejecutar lo que describe, con la función de 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... 

La variable de índice cuenta la fila en la que se encuentra, por lo que puede usarse en lugar de rango o rango. Este método es bastante sencillo y funciona con iteradores a diferencia del rango o corte, y también se puede usar con el límite inferior, si se desea. ¡Aclamaciones!

De la documentación :

Nota: cuando se crea una hoja de cálculo en la memoria, no contiene celdas. Se crean cuando se accede por primera vez. De esta manera, no creamos objetos a los que nunca se podría acceder, lo que reduce la huella de memoria.

Advertencia: debido a esta función, desplazarse por las celdas en lugar de acceder directamente a ellas las creará todas en la memoria, incluso si no les asigna un valor. Algo como

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

Creará 100×100 celdas en memoria, para nada.

Sin embargo, hay una manera de limpiar todas esas celdas no deseadas, eso lo veremos más adelante.

Creo que acceder a las propiedades de las columnas o filas hará que muchas celdas tengan que cargarse en la memoria. Sugeriría solo intentar acceder directamente a las celdas que necesita.

p.ej.

 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