Python:如何将巨大的文本文件读入内存

2024-02-08

我在配备 1GB RAM 的 Mac Mini 上使用 Python 2.6。我想读取一个巨大的文本文件

$ ls -l links.csv; file links.csv; tail links.csv 
-rw-r--r--  1 user  user  469904280 30 Nov 22:42 links.csv
links.csv: ASCII text, with CRLF line terminators
4757187,59883
4757187,99822
4757187,66546
4757187,638452
4757187,4627959
4757187,312826
4757187,6143
4757187,6141
4757187,3081726
4757187,58197

因此文件中的每一行都包含两个逗号分隔的整数值的元组。 我想读入整个文件并根据第二列对其进行排序。我知道,我可以在不将整个文件读入内存的情况下进行排序。但我认为对于 500MB 的文件,我仍然可以在内存中完成它,因为我有 1GB 可用空间。

然而,当我尝试读入该文件时,Python 似乎分配的内存比磁盘上文件所需的内存多得多。因此,即使有 1GB 的 RAM,我也无法将 500MB 的文件读入内存。 我用于读取文件并打印有关内存消耗的一些信息的 Python 代码是:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys

infile=open("links.csv", "r")

edges=[]
count=0
#count the total number of lines in the file
for line in infile:
 count=count+1

total=count
print "Total number of lines: ",total

infile.seek(0)
count=0
for line in infile:
 edge=tuple(map(int,line.strip().split(",")))
 edges.append(edge)
 count=count+1
 # for every million lines print memory consumption
 if count%1000000==0:
  print "Position: ", edge
  print "Read ",float(count)/float(total)*100,"%."
  mem=sys.getsizeof(edges)
  for edge in edges:
   mem=mem+sys.getsizeof(edge)
   for node in edge:
    mem=mem+sys.getsizeof(node) 

  print "Memory (Bytes): ", mem 

我得到的输出是:

Total number of lines:  30609720
Position:  (9745, 2994)
Read  3.26693612356 %.
Memory (Bytes):  64348736
Position:  (38857, 103574)
Read  6.53387224712 %.
Memory (Bytes):  128816320
Position:  (83609, 63498)
Read  9.80080837067 %.
Memory (Bytes):  192553000
Position:  (139692, 1078610)
Read  13.0677444942 %.
Memory (Bytes):  257873392
Position:  (205067, 153705)
Read  16.3346806178 %.
Memory (Bytes):  320107588
Position:  (283371, 253064)
Read  19.6016167413 %.
Memory (Bytes):  385448716
Position:  (354601, 377328)
Read  22.8685528649 %.
Memory (Bytes):  448629828
Position:  (441109, 3024112)
Read  26.1354889885 %.
Memory (Bytes):  512208580

仅读取 500MB 文件的 25% 后,Python 就消耗了 500MB。因此,将文件内容存储为整数元组列表似乎内存效率不高。 有没有更好的方法来做到这一点,以便我可以将 500MB 文件读入 1GB 内存?


有一个方法可以对大于 RAM 的文件进行排序在本页 http://code.activestate.com/recipes/466302/,但您必须根据涉及 CSV 格式数据的情况对其进行调整。那里还有其他资源的链接。

Edit:诚然,磁盘上的文件并不“大于 RAM”,但内存中的表示很容易变得比 RAM 大得多可用内存。一方面,您自己的程序无法获得整个 1GB(操作系统开销等)。另一方面,即使您以纯 Python 最紧凑的形式存储它(两个整数列表,假设 32 位机器等),您也会为这 30M 整数对使用 934MB。

使用 numpy 也可以完成这项工作,仅使用大约 250MB。这种方式加载并不是特别快,因为您必须计算行数并预先分配数组,但考虑到它在内存中,它可能是最快的实际排序:

import time
import numpy as np
import csv

start = time.time()
def elapsed():
    return time.time() - start

# count data rows, to preallocate array
f = open('links.csv', 'rb')
def count(f):
    while 1:
        block = f.read(65536)
        if not block:
             break
        yield block.count(',')

linecount = sum(count(f))
print '\n%.3fs: file has %s rows' % (elapsed(), linecount)

# pre-allocate array and load data into array
m = np.zeros(linecount, dtype=[('a', np.uint32), ('b', np.uint32)])
f.seek(0)
f = csv.reader(open('links.csv', 'rb'))
for i, row in enumerate(f):
    m[i] = int(row[0]), int(row[1])

print '%.3fs: loaded' % elapsed()
# sort in-place
m.sort(order='b')

print '%.3fs: sorted' % elapsed()

在我的机器上输出与您显示的示例文件类似的内容:

6.139s: file has 33253213 lines
238.130s: read into memory
517.669s: sorted

numpy 中的默认值是快速排序 http://en.wikipedia.org/wiki/Quicksort。 ndarray.sort() 例程(就地排序)也可以采用关键字参数kind="mergesort" or kind="heapsort"但似乎这些都无法对记录数组 http://www.scipy.org/RecordArrays顺便说一句,我用它作为我能看到的对列进行排序的唯一方法together与默认情况相反,默认情况下会对它们进行独立排序(完全弄乱您的数据)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python:如何将巨大的文本文件读入内存 的相关文章

随机推荐

  • ng2-文件上传访问控制来源问题

    我已经使用这个库进行 angular2 文件上传https github com valor software ng2 file upload https github com valor software ng2 file upload
  • 无法编译调用 tgkill 的程序

    我正在尝试编写一个使用 tgkill 向特定线程发送信号的程序 但是每当我用 gcc 编译它时 我都会收到有关 tgkill 未定义引用的错误 我尝试使用 lpthread 进行编译 但没有帮助 我用谷歌搜索了又搜索 但找不到任何答案 我如
  • .NET Excel 文件解析器

    因此 我工作的公司正在寻找一种方法来验证给定的 xls xlsx 文件是否有效 这意味着检查列 行和其他数据 他让我评估 GrapeCity Spread 和 SpreadsheetGear 但我想知道是否还有其他人可以查看其他外部工具的建
  • 如何解析flutter中的map Json列表?

    I have one Json structure with three maps one is list of products then total and tax I have to parse this json structure
  • 如何知道 npm `unzip` 模块何时完成解压文件?

    我正在使用unzip来自 npm 的模块用于提取 zip 存档的内容 我需要知道何时完成提取并且文件已完全写入磁盘 My code fs createReadStream master zip pipe unzip Extract path
  • C++ 中用于分离标头/源的模板专业化的稳健方法是什么

    在中等规模甚至大型复杂项目中 将模板声明和定义分开是有用的 以减少编译时间 然而 在复杂的代码中 程序员的小错误可能会导致不被注意的行为变化 例如调用通用版本而不是专门化版本 例子 由于错过了声明 模板专业化变得不可见 file A hpp
  • 如何将 Emacs 与 Python 结合使用

    我是 emacs 新手 我想使用 emacs 进行 python 开发 我使用的是 Ubuntu 9 10 我对让 emacs 与 python 一起工作感到沮丧 我使用 GNU Emacs 23 1 50 1 x86 64 pc linu
  • 以渐变方式绘制背景颜色

    此代码生成下面的第一个图 water height lt seq 0 5 1 y lt seq 0 1500 length out 6 df lt data frame water height y library ggplot2 ggpl
  • vb.net 中可以实现内联函数吗?

    问题在标题中 我看到的答案假设您正在谈论编译或 JIT 时内联 它们是完全正确的 然而 我听说过的 内联 一词的另一种用法是用于 lambda 表达式之类的东西 在 C 中 例如 public IEnumerable
  • 在 Android 上安装预构建的二进制文件:“未找到”

    我正在尝试在自定义 Android 映像中安装预构建的二进制文件 为此 我已将其复制到新目录中prebuilt android arm 与Android mk文件类似于此 LOCAL PATH call my dir include CLE
  • 进程地址空间与虚拟内存

    根据我阅读几篇文章的理解 我假设进程地址空间 PAS 和虚拟内存 VM 是相同的 难道是我的理解有问题 有人可以解释一下这一点并启发我吗 我很困惑 我知道进程地址空间与 RAM 或物理内存无关 但只是对 PAS 和 VM 感到困惑 Firs
  • 在 pandas 数据框中解析/分割 URL 的 pythonic 方法

    我有一个 df 它在标记为 url 的列中为不同的用户提供了数千个链接 如下所示 https www google com something https mail google com anohtersomething https cal
  • SWT 图像与字符串之间的转换

    我正在尝试将 SWT 图像转换为字符串 反之亦然 至字符串 Display display new Display final Image image new Image display c test png Looks good show
  • iOS 和 Safari 11 WebRTC 不收集 STUN/TURN Trickle ICE 候选者

    在 iOS 11 iPhone 5s 和 iPhone 7 或桌面上使用 Safari 11 时 我的 Web 应用程序无法通过 CoTURN 服务器收集 WebRTC 中继 ICE 候选项 Web 应用程序 建立单向音频 WebRTC 对
  • 如何使用 PythonNET 和 C#.NET 将枚举放入列表中?

    我有一个通过 Python 与 PythonNET 一起使用的 NET 库 但不知道如何将枚举放入列表中 Python 似乎将枚举转换为不适合列表数据类型的整数 这是一个例子 import clr from System Collectio
  • 错误消息“无法安装或运行应用程序。该应用程序需要 GAC 中的 stdole 版本 7.0.3300.0”

    当一位用户尝试运行该应用程序时 我们的 ClickOnce 应用程序将报告 无法安装或运行该应用程序 该应用程序需要 GAC 中的 stdole 版本 7 0 3300 0 有趣的是 GAC http en wikipedia org wi
  • 在ios中获取状态栏的正确颜色

    好吧 我在为状态栏着色时遇到一些麻烦 我有一个非常简单的应用程序 可以在两个视图之间移动 我尝试用此代码为导航控制器的状态栏着色 UINavigationBar appearance setBarTintColor UIColorFromR
  • R Shiny - 在单选按钮中没有选择初始值?

    从文档中 radioButtons inputId 标签 选择 选择 NULL 内联 FALSE 宽度 空 论点 selected最初选择的值 如果未指定则默认为第一个值 但是 你能指定selected参数使得渲染的单选按钮没有选择初始值
  • Haskell 的foldr 函数有多少个参数?

    我是 Haskell 的新手 我正在读这本书 真实世界的哈斯克尔 http book realworldhaskell org read functional programming html fp tailrecursion 在本书的第
  • Python:如何将巨大的文本文件读入内存

    我在配备 1GB RAM 的 Mac Mini 上使用 Python 2 6 我想读取一个巨大的文本文件 ls l links csv file links csv tail links csv rw r r 1 user user 469