Python:快速加载7 GB文本文件为Unicode字符串

2 投票
3 回答
880 浏览
提问于 2025-04-16 03:44

我有一个很大的文本文件夹,差不多有7GB的文件。我需要快速把这些文件加载到Python的unicode字符串中,使用的是iPython。我总共有15GB的内存。(我在用EC2,如果真的需要的话,可以再买更多内存。)

直接读取这些文件对我来说太慢了。我试过把文件复制到一个内存盘上,然后再从那里加载到iPython中。这样速度快了一些,但iPython崩溃了(可能是内存不够用了?)这是我设置内存盘的代码:

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

有没有人有什么好主意?基本上,我想要的是可以在内存中持久存在的Python对象。由于使用iPython,我不能用IncPy:http://www.stanford.edu/~pgbovine/incpy.html

谢谢!

3 个回答

0

给未来看到这个内容的人:

关于如何配置你的磁盘数据和内存数据一致,然后使用mmap,这个方向是对的。当你这样做的时候,你还可以用一个内存盘(ramdisk)来支持它。因为数据是通过mmap映射的,所以在处理数据时,Python端的内存不会大幅增加。

  • 把你的数据转换成字节,去掉unicode字符等。每个字符应该只占用一个字节。
  • 访问数据时一定要使用mmap。
  • 安排你的数据,尽量减少磁盘访问,让它在磁盘上的使用尽可能高效。
  • 把数据移动到内存盘上以便实时使用。
2

我看到你提到IncPy和IPython,所以我想推荐一个我的项目,它有点像IncPy,但它是和IPython一起工作的,而且特别适合处理大数据:http://packages.python.org/joblib/

如果你把数据存储在numpy数组里(字符串也可以存放在numpy数组中),那么joblib可以使用memmap来处理中间结果,这样在输入输出时会更高效。

3

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

  • 关于ipython的需求。你为什么需要在ipython中处理这么大的数据文件,而不是用一个独立的脚本呢?
  • 关于tmpfs内存磁盘。我理解你的问题是你在Python中一次性把所有输入数据都读入内存。如果真是这样的话,Python会自己分配缓冲区来存放所有数据,而tmpfs文件系统只有在你多次从内存磁盘重新加载数据时才会提高性能。
  • 提到IncPy。如果你的性能问题可以通过记忆化(memoization)来解决,为什么不直接手动为最需要的函数实现记忆化呢?

所以,如果你确实需要一次性把所有数据都放在内存中——比如你的算法需要多次处理整个数据集——我建议你看看mmap模块。这个模块会以原始字节的形式提供数据,而不是unicode对象,这可能会让你的算法多一些工作(比如处理编码后的数据),但会合理地使用内存。一次性把数据读入Python的unicode对象会需要占用2倍或4倍于磁盘上数据的内存(假设数据是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)

我希望这至少能让你更接近答案。

撰写回答