【问题标题】:Writing pandas data to Excel with efficient memory usage [duplicate]以高效的内存使用将熊猫数据写入Excel [重复]
【发布时间】:2020-07-18 00:58:02
【问题描述】:

我正在使用df.to_excel() 成功地将数据帧写入 Excel。不幸的是,这很慢并且会消耗大量内存。数据集越大,它消耗的内存就越多,直到(对于我需要处理的最大数据集)服务器资源匮乏。

我发现使用df.to_csv() 方法可以提供方便的chunksize=nnnn 参数。这要快得多,并且几乎不消耗额外的内存。精彩的!我将最初写入 .csv,然后在另一个过程中将 .csv 转换为 .xlsx。我尝试使用 openpyxl 执行此操作,但我发现的每个解决方案一次遍历 csv 数据一行,附加到工作簿工作表,例如

with open(temporary_filepath, 'r') as f:
    for row in csv.reader(f):
        ws.append(row)
wb.save()

这可行,但是当我查看我的资源监视器时,消耗的内存和速度一样慢(我现在假设原来的 df.to_excel() 在内部做同样的事情)。所以这种方法毕竟并没有让我走出困境。

我曾假设我可以做一些相当于 File | 的事情。另存为,但在 Python 中,例如将整个 csv 读入一个 openpyxl 工作簿并一次性将其保存到一个文件中,无需迭代,但要么这是不可能的,要么我找不到上面的文档。

考虑到一个非常大的 Pandas 数据框和输出 .xlsx(不是 .csv)的要求,低内存消耗的最佳方法是什么?是否可以使用 Pandas 或 Openpyxl有效地完成,或者是否有更好的工具来完成这项工作?

更新: 看起来 pyexcel 有一个 Save As 方法可以解决问题。如果可能的话,宁愿不向堆栈中添加另一个电子表格库,但如果在 pandas 或 openpyxl 中没有等效项,则会这样做。有人用过吗?

【问题讨论】:

  • openpyxl 和 xlsxwriter 都有将行直接流式传输到临时文件的模式,这大大减少了内存使用。
  • @CharlieClark 这很有趣。您指的是stackoverflow.com/a/55144731/8438 此处显示的 BytesIO 技术吗?
  • 不,在 openpyxl 中只使用只写模式:Workbook(write_only=True)
  • @CharlieClark 非常有趣,感谢您的提示。

标签: python excel pandas csv openpyxl


【解决方案1】:

也许您可以使用库 pyexcelerate - https://github.com/kz26/PyExcelerate。他们已经在他们的 github repo 上发布了基准测试


from pyexcelerate import Workbook

values = [df.columns] + list(df.values)
wb = Workbook()
wb.new_sheet('data_sheet_name', data=values)
wb.save('data.xlsx')

【讨论】:

  • 感谢@bigbounty,这看起来正是我们想要的。
  • 链接的基准测试非常过时,pyexcelerate 在对 OOXML 的支持方面非常有限。 openpyxl 有自己更详细的基准测试:openpyxl.readthedocs.io/en/latest/performance.html 归根结底,功能和性能之间存在权衡。
  • @CharlieClark 链接已删除。
【解决方案2】:

pyexcelerate 回复正是我所问的,所以我接受了这个答案,但只是想发布一个更新,我们找到了一个可能更容易的替代解决方案。在这里分享,以防有用。

Pandas 现在更喜欢 xlsxwriter 而不是 openpyxl。如果它已安装,并且您未指定引擎,则默认使用 xlsxwriter(或者当然您可以明确指定它)。在我的实验中,在写入 Excel 的任务中,xlsxwriter 的内存效率比 openpyxl 高 4 倍。这不是一个无限可扩展的解决方案 - 仍然可以想象,即使经过这种优化,它仍然可以接收到如此大的数据集,以至于它仍然会压倒内存 - 但它非常简单:只需 pip install xlsxwriter 并且调用 @987654323 时内存使用量会增加 4 倍@,没有代码更改(在我的情况下)。

【讨论】:

  • Pandas 一直默认使用 xlsxwriter,如果您所做的只是创建新文件,这很好。但如果内存可能是个问题,那么建议完全避免使用to_excel() 并直接使用库。
猜你喜欢
  • 2020-05-18
  • 2021-08-05
  • 1970-01-01
  • 2018-11-11
  • 1970-01-01
  • 2021-03-25
  • 2016-08-08
  • 1970-01-01
  • 2015-06-15
相关资源
最近更新 更多