Python:快速将 7 GB 文本文件加载到 unicode 字符串中

问题描述 投票:0回答:3

我有一个很大的文本文件目录——大约 7 GB。我需要将它们快速加载到 iPython 中的 Python unicode 字符串中。我总共有 15 GB 内存。 (我使用的是 EC2,所以如果绝对必要的话我可以购买更多内存。)

仅读取文件对于我的目的来说太慢了。我尝试将文件复制到 ramdisk,然后将它们从那里加载到 iPython 中。这加快了速度,但 iPython 崩溃了(没有剩余足够的内存?)这是 ramdisk 设置:

mount -t tmpfs none /var/ramdisk -o size=7g

有人有什么想法吗?基本上,我正在寻找持久的内存中 Python 对象。 iPython 要求不允许使用 IncPy:http://www.stanford.edu/~pgbovine/incpy.html .

谢谢!

python memory ctypes shared-memory ipython
3个回答
3
投票

这里有很多令人困惑的地方,这使得回答这个问题变得更加困难:

  • ipython 要求。为什么需要在 ipython 中处理如此大的数据文件而不是独立的脚本?
  • tmpfs RAM 磁盘。我读到你的问题暗示你在Python中一次将所有输入数据读入内存。如果是这种情况,那么 python 会分配自己的缓冲区来保存所有数据,而 tmpfs 文件系统只会在您多次从 RAM 磁盘重新加载数据时才能获得性能提升。
  • 提到 IncPy。如果您的性能问题可以通过记忆来解决,为什么不能手动为最有帮助的功能实现记忆?

所以。如果您实际上需要一次将所有数据存储在内存中——例如,如果您的算法多次重新处理整个数据集——我建议您查看

mmap
模块。这将以原始字节而不是
unicode
对象的形式提供数据,这可能需要在算法中进行更多的工作(例如,对编码数据进行操作),但会使用合理的内存量。将数据一次性读入 Python
unicode
对象将需要 2 倍或 4 倍的 RAM 占用磁盘空间(假设数据为 UTF-8)。

如果您的算法只是对数据进行一次线性传递(就像您提到的 Aho-Corasick 算法一样),那么您最好一次只读取合理大小的块:

with codecs.open(inpath, encoding='utf-8') as f:
    data = f.read(8192)
    while data:
        process(data)
        data = f.read(8192)

我希望这至少能让你们更亲近。


2
投票

我在你的问题中看到了 IncPy 和 IPython 的提及,所以让我插入一个我的项目,该项目有点朝着 IncPy 的方向,但与 IPython 一起使用并且非常适合大数据:http://packages .python.org/joblib/

如果您将数据存储在 numpy 数组中(字符串可以存储在 numpy 数组中),joblib 可以使用 memmap 来获取中间结果并提高 IO 效率。


0
投票

对于将来发现此内容的任何人:

有关配置磁盘数据以匹配内存数据然后使用 mmap 的评论是正确的方向。当您执行此操作时,您还可以使用 ramdisk 来支持它,并且由于数据已映射,因此在处理数据时,Python 端的内存不会大量增加。

  • 将数据转换为字节,删除 unicode 字符等。每个字符只能是一个字节。
  • 始终使用 mmap 来访问您的数据
  • 安排数据,尽量减少磁盘访问,并在磁盘上尽可能高效
  • 将数据移动到ramdisk以供实时使用
© www.soinside.com 2019 - 2024. All rights reserved.