【发布时间】:2017-04-08 19:17:50
【问题描述】:
我想知道如何在不使用 python 的 win32com 客户端从 excel 表中迭代的情况下读取整列。
【问题讨论】:
我想知道如何在不使用 python 的 win32com 客户端从 excel 表中迭代的情况下读取整列。
【问题讨论】:
您可以使用Range 集合读取整列而无需从工作表中进行迭代。如果您担心性能问题,您应该永远不要使用Cells。 Python 使用 win32com 模块与 Excel COM 库进行交互。每当您使用 Python 和 COM(Excel、PowerPoint、Acess、ADODB 等)时,最大的性能限制之一就是 COM 和 Python 之间的 IO。使用Range 方法,您只需调用一个COM 方法,而使用Cells,您为每一行调用一个。如果您在 VBA 或 .NET 中执行相同操作,这也会更快
在以下测试中,我在单元格 A1 到 A2000 中创建了一个包含 10 个随机字符的工作表。然后我使用 Range 和 Cells 将这些值提取到列表中。
import win32com.client
app = win32com.client.Dispatch("Excel.Application")
s = app.ActiveWorkbook.Sheets(1)
def GetValuesByCells():
startTime = time.time()
vals = [s.Cells(r,1).Value for r in range(1,2001)]
return time.time() - startTime
def GetValuesByRange():
startTime = time.time()
vals = [v[0] for v in s.Range('A1:A2000').Value]
return time.time() - startTime
>>> GetValuesByRange()
0.03600001335144043
>>> GetValuesByCells()
5.27400016784668
在这种情况下,Range 比 Cells 快 2 个数量级 (146x)。请注意,Range 方法返回一个 2D 列表,其中每个内部列表都是一行。列表迭代将vals 转置为一个二维列表,其中内部列表是一列。
【讨论】:
win32com”。
xlrd 的效果如何。如果差异很小,那么 xlrd 将是一个明显的赢家
您查看过openpyxl 库吗?来自文档:
from openpyxl import load_workbook
wb = load_workbook(filename='file.xlsx')
ws = wb.get_sheet_by_name(name='Sheet1')
columns = ws.columns()
还支持迭代器和其他好东西。
【讨论】:
最快的方法是通过win32com.client API 使用内置的Range 功能。但是,我不是它的忠实粉丝。我认为 API 令人困惑且文档记录不完善,而且使用它不是很 Python (但这只是我)。
如果效率对您来说不是问题,您可以使用出色的 xlrd 库。像这样:
import xlrd
book = xlrd.open_workbooks('Book1')
sheet = book.sheet_by_name('Sheet1')
sheel.col(1)
sheet.col(2)
# and so on...
这为您提供了单元格对象。要获得纯值,请使用sheet.col_values(还有其他一些非常适合使用的方法)。
请记住,xlrd 代表“excel read”,所以如果你想写入一个 excel 文件,你需要一个名为“xlwt”的不同库(这也很不错,虽然在我看来不如 xlrd)。
【讨论】:
SELECT 从数据库中检索结果集。也就是说,在检索期间必须完成的任何“迭代”都会在到达 Python 之前处理。在数据库的情况下,SQL 引擎可能会在后台进行迭代,但您所看到的只是一个单个“返回值”,其中恰好包含多个值。因此,对于 Excel,OP 正在寻找指定一个范围,然后“一次”将所有值抓取到一个元组中。这可能会也可能不会;我不太了解 COM。
xlrd 直接读取文件(根本不涉及COM)通常足够快。