¿Cómo se convierte un rango de win32com.client en un DataFrame de Pandas?
Estoy escribiendo algunas macros que llaman código de Python para realizar operaciones en rangos de Excel. Es mucho más fácil realizar muchas de las operaciones requeridas con pandas en Python. Como quiero hacer esto mientras la hoja de cálculo está abierta (y es posible que no se haya guardado), estoy utilizando win32com.client
para leer un rango de celdas y convertirlo en un dataframe de Pandas. Sin embargo, esto es extremadamente lento, presumiblemente porque la forma en que lo calculo es muy ineficiente:
import datetime
import pytz
import pandas
import time
import win32com.client
def rango_a_tabla(rangoExcel, tsy, tsx, altura, ancho, agregar_referencias_celdas = True):
ii = 0
claves = []
while ii < ancho:
claves.append(str(rangoExcel[ii]))
ii += 1
numerosColumnas = {clave:jj+tsx for jj, clave in enumerate(claves)}
claves.append('numeroFila')
midiccionario = {clave:[] for clave in claves}
while ii < ancho*altura:
midiccionario[claves[ii%ancho]].append(rangoExcel[ii].value)
ii += 1
for yy in range(tsy + 1, tsy + 1 + altura - 1): # sumar 1 para no incluir la cabecera
midiccionario['numeroFila'].append(yy)
return (midiccionario, numerosColumnas)
ExcelApp = win32com.client.GetActiveObject('Excel.Application')
wb = ExcelApp.Workbooks('miarchivo.xlsm')
numHoja = [hoja.Nombre for hoja in wb.Hojas].index("nombre_de_mi_hoja") + 1
ws = wb.Worksheets(numHoja)
altura = int(ws.Cells(1, 3)) # obtener altura de la tabla desde la fórmula en la hoja de cálculo de Excel
ancho = int(ws.Cells(1, 2)) # obtener ancho de la tabla desde la fórmula en la hoja de cálculo de Excel
miRango = ws.Range(ws.Cells(2, 1), ws.Cells(2 + altura - 1, 1 + ancho - 1))
df, numerosColumnas = rango_a_tabla(miRango, 1, 1, altura, ancho)
df = pandas.DataFrame.from_dict(df)
Esto funciona, pero la función rango_a_tabla
que escribí es extremadamente lenta para tablas grandes, ya que itera sobre cada celda una por una.
Sospecho que probablemente haya una forma mucho mejor de convertir el objeto Range de Excel en un dataframe de Pandas. ¿Conoce alguna forma mejor de hacerlo?
Aquí hay un ejemplo simplificado de cómo se vería mi rango:
Las variables altura
y ancho
en el código son simplemente tomadas de las celdas inmediatamente arriba de la tabla:
¿Alguna idea aquí, o simplemente tendré que guardar el libro de trabajo y usar Pandas para leer la tabla desde el archivo guardado?
davy.ai
Una posible solución para acelerar la conversión de un objeto de rango de Excel a un dataframe de Pandas es utilizar la biblioteca
numpy
para crear un arreglo de NumPy a partir del objeto de rango de Excel y luego convertirlo a un dataframe de Pandas.numpy
generalmente es más rápido al recorrer arreglos y puede manejar conjuntos de datos más grandes de manera más eficiente. Aquí tienes un ejemplo de implementación:Esta implementación utiliza el método
np.array
para crear un arreglo de NumPy a partir del rango de Excel, elimina la primera fila (que contiene los encabezados de columna) y luego crea un dataframe de Pandas a partir del arreglo de NumPy. Luego agrega los encabezados de columna de la primera fila del rango de Excel y una columna de número de fila. Finalmente, convierte las columnas al tipo de dato adecuado (por ejemplo, una columna de fecha a un objeto datetime de Pandas).Este enfoque debería ser más rápido que iterar sobre las celdas del rango de Excel una por una. Sin embargo, es importante tener en cuenta que la velocidad de la conversión dependerá en última instancia del tamaño del rango de Excel y del poder de procesamiento de la computadora en la que se ejecute el código.