效率:openpyxl还是VBA?
Efficiency: openpyxl or VBA?
我正在尝试找出对于类似任务通常哪个更快:使用 VBA 或 openpyxl。
我知道这可能取决于你想要完成的任务,但是 假设我有一个 table 宽 50 个单元格,高 150,000 个单元格,我想从工作簿 A 到工作簿 B.
关于 python 是否会做得更好或者 Excel 是否更好地处理自己有什么想法吗?
我的直觉告诉我 python 应该相当快 出于某些原因:
- 为了让子从一个工作簿复制到另一个工作簿,两者都应该打开并且 运行,而使用 python 我可以简单地加载两者;
- VBA 必须处理大多数任务的大量混乱,并且占用大量系统资源
除此之外,我想知道我是否可以对 openpyxl 脚本做一些进一步的改进,比如多线程或者可能与它一起使用 NumPy。
感谢您的帮助!
TBH 最快的方法可能是使用 xlwings 远程控制 Excel,因为这可以利用 Excel 的优化。 VBA 可能也可以连接到它,但我从来没有发现 VBA 很快。
Python 必须从 XML 转换为 Python,然后再转换回 XML。你有大约 5,000,000 百万个单元格,所以我预计这在我的机器上大约需要一分钟。我建议结合只读和只写模式来执行此操作以保持低内存使用率。
如果您只有数字数据(没有日期),那么您也许可以找到一个快捷方式和 "transplant" 相关工作表 XML 文件从一个 Excel 文件到另一个文件,然后只需更改相关元数据即可。
TL;DR 考虑直接连接到 Excel 文件(ADO in VBA or Python+PyWin32, pyodbc在 Python 或 .NET OleDbConnection
class 等中)。您建立这种联系所用的语言无关紧要。
长版
如果您只想处理数据本身,您可能需要考虑使用 ADO、pyodbc 或 .NET OleDbConnection
class 直接连接到 Excel .
自动化 Excel 应用程序(使用 Microsoft Excel 对象模型,或(大概)使用 xlwings)会产生大量开销,这是可以理解的,因为您可能不仅仅阅读Excel 文件中的数据,还可以操作 Excel UI 中的所有对象 — windows、菜单 — 以及数据之外的对象,例如对个人进行格式化单元格或范围。
确实 openpyxl 没有 UI 元素的所有这些开销,因为它直接读取文件,但我假设仍然会产生一些开销,因为 openpyxl 必须提供所有文件中的信息,这不仅仅是数据 — 例如,单元格格式。
建立数据连接还允许您将 Excel 文件视为一个数据库,您可以向其发出 SQL 语句,并具有 SQL -- 连接的所有功能, 排序, 分组, 聚合。
有关使用 ADO 和 VBA 的示例,请参阅 here。
与openpyxl
...
这个 link 对我很有帮助:
https://blog.dchidell.com/2019/06/24/openpyxl-poor-performance-optimisation/
Use read_only when opening the file if all you're doing is reading.
Use the built in iterators!
I cannot stress this enough - the iterators are fast, crazy fast.
- Call functions as infrequently as possible and store intermediate
data in variables. It may bulk the code up a bit, but it tends to be
more efficient and also allows your code to be more readable (but this
is icing on the cake compared to points 1 and 2). Python can also be
ambiguous as to what is a variable and what is a function; but as a
general rule intermediate variables are good for multiple function
calls.
我正在阅读特定工作簿中的值,我最初是这样做的:
wb = load_workbook(filename)
这将花费将近 80 秒。在操作之间缓存工作簿很有帮助,但每次重新加载脚本时仍然很痛苦。
我切换到只读。
wb = load_workbook(filename, data_only=True, read_only=True)
现在只需 < 0.1 秒。
我正在尝试找出对于类似任务通常哪个更快:使用 VBA 或 openpyxl。
我知道这可能取决于你想要完成的任务,但是 假设我有一个 table 宽 50 个单元格,高 150,000 个单元格,我想从工作簿 A 到工作簿 B.
关于 python 是否会做得更好或者 Excel 是否更好地处理自己有什么想法吗?
我的直觉告诉我 python 应该相当快 出于某些原因:
- 为了让子从一个工作簿复制到另一个工作簿,两者都应该打开并且 运行,而使用 python 我可以简单地加载两者;
- VBA 必须处理大多数任务的大量混乱,并且占用大量系统资源
除此之外,我想知道我是否可以对 openpyxl 脚本做一些进一步的改进,比如多线程或者可能与它一起使用 NumPy。
感谢您的帮助!
TBH 最快的方法可能是使用 xlwings 远程控制 Excel,因为这可以利用 Excel 的优化。 VBA 可能也可以连接到它,但我从来没有发现 VBA 很快。
Python 必须从 XML 转换为 Python,然后再转换回 XML。你有大约 5,000,000 百万个单元格,所以我预计这在我的机器上大约需要一分钟。我建议结合只读和只写模式来执行此操作以保持低内存使用率。
如果您只有数字数据(没有日期),那么您也许可以找到一个快捷方式和 "transplant" 相关工作表 XML 文件从一个 Excel 文件到另一个文件,然后只需更改相关元数据即可。
TL;DR 考虑直接连接到 Excel 文件(ADO in VBA or Python+PyWin32, pyodbc在 Python 或 .NET OleDbConnection
class 等中)。您建立这种联系所用的语言无关紧要。
长版
如果您只想处理数据本身,您可能需要考虑使用 ADO、pyodbc 或 .NET OleDbConnection
class 直接连接到 Excel .
自动化 Excel 应用程序(使用 Microsoft Excel 对象模型,或(大概)使用 xlwings)会产生大量开销,这是可以理解的,因为您可能不仅仅阅读Excel 文件中的数据,还可以操作 Excel UI 中的所有对象 — windows、菜单 — 以及数据之外的对象,例如对个人进行格式化单元格或范围。
确实 openpyxl 没有 UI 元素的所有这些开销,因为它直接读取文件,但我假设仍然会产生一些开销,因为 openpyxl 必须提供所有文件中的信息,这不仅仅是数据 — 例如,单元格格式。
建立数据连接还允许您将 Excel 文件视为一个数据库,您可以向其发出 SQL 语句,并具有 SQL -- 连接的所有功能, 排序, 分组, 聚合。
有关使用 ADO 和 VBA 的示例,请参阅 here。
与openpyxl
...
这个 link 对我很有帮助:
https://blog.dchidell.com/2019/06/24/openpyxl-poor-performance-optimisation/
Use read_only when opening the file if all you're doing is reading.
Use the built in iterators!
I cannot stress this enough - the iterators are fast, crazy fast.
- Call functions as infrequently as possible and store intermediate data in variables. It may bulk the code up a bit, but it tends to be more efficient and also allows your code to be more readable (but this is icing on the cake compared to points 1 and 2). Python can also be ambiguous as to what is a variable and what is a function; but as a general rule intermediate variables are good for multiple function calls.
我正在阅读特定工作簿中的值,我最初是这样做的:
wb = load_workbook(filename)
这将花费将近 80 秒。在操作之间缓存工作簿很有帮助,但每次重新加载脚本时仍然很痛苦。
我切换到只读。
wb = load_workbook(filename, data_only=True, read_only=True)
现在只需 < 0.1 秒。