【发布时间】:2022-01-04 23:03:36
【问题描述】:
我正在编写一些宏,它们调用 Python 代码来对 Excel 中的范围执行操作。在 Python 中使用 pandas 执行许多所需的操作要容易得多。因为我想在电子表格打开(并且可能尚未保存)时执行此操作,所以我使用win32com.client 读取一系列单元格以转换为 Pandas 数据框。但是,这非常慢,大概是因为我计算它的方式非常低效:
import datetime
import pytz
import pandas
import time
import win32com.client
def range_to_table(excelRange, tsy, tsx, height, width, add_cell_refs = True):
ii = 0
keys = []
while ii < width:
keys.append(str(excelRange[ii]))
ii += 1
colnumbers = {key:jj+tsx for jj, key in enumerate(keys)}
keys.append('rownumber')
mydict = {key:[] for key in keys}
while ii < width*height:
mydict[keys[ii%width]].append(excelRange[ii].value)
ii += 1
for yy in range(tsy + 1, tsy + 1 + height - 1): # add 1 to not include header
mydict['rownumber'].append(yy)
return (mydict, colnumbers)
ExcelApp = win32com.client.GetActiveObject('Excel.Application')
wb = ExcelApp.Workbooks('myworkbook.xlsm')
sheet_num = [sheet.Name for sheet in wb.Sheets].index("myworksheet name") + 1
ws = wb.Worksheets(sheet_num)
height = int(ws.Cells(1, 3)) # obtain table height from formula in excel spreadsheet
width = int(ws.Cells(1, 2)) # obtain table width from formula in excel spreadsheet
myrange = ws.Range(ws.Cells(2, 1), ws.Cells(2 + height - 1, 1 + width - 1))
df, colnumbers = range_to_table(myrange, 1, 1, height, width)
df = pandas.DataFrame.from_dict(df)
这可行,但我编写的 range_to_table 函数对于大型表格来说非常慢,因为它会逐个遍历每个单元格。
我怀疑可能有更好的方法将 Excel Range 对象转换为 Pandas 数据框。你知道更好的方法吗?
这是我的范围的简化示例:
代码中的height 和width 变量只是取自表格上方的单元格:
这里有什么想法,还是我只需要保存工作簿并使用 Pandas 从保存的文件中读取表格?
【问题讨论】:
标签: python excel pandas win32com