python读取大的json文件 - 大数据的文件如何读取




如何在python中逐行读取大文件 (7)

我想遍历整个文件的每一行。 一种方法是读取整个文件,将其保存到列表中,然后转到感兴趣的行。 这种方法使用了大量的内存,所以我正在寻找替代方案。

我的代码到目前为止:

for each_line in fileinput.input(input_file):
    do_something(each_line)

    for each_line_again in fileinput.input(input_file):
        do_something(each_line_again)

执行此代码会给出错误消息: device active

有什么建议么?

编辑:目的是计算成对的字符串相似性,这意味着文件中的每一行,我想要计算每隔一行的Levenshtein距离。


剥离换行符:

with open(file_path, 'rU') as f:
    for line_terminated in f:
        line = line_terminated.rstrip('\n')
        ...

对于通用换行符支持 ,无论文件中的终结符'\r''\n'还是'\r\n' ,所有文本文件行似乎都以'\n'结尾。

编辑 -指定通用换行支持:

  • Unix上的Python 2 - open(file_path, mode='rU') - 必需[谢谢@Dave ]
  • Windows上的Python 2 - open(file_path, mode='rU') - 可选
  • Python 3 - open(file_path, newline=None) - 可选

newline参数仅在Python 3中受支持,并且默认为None 。 在所有情况下, mode参数默认为'r'U在Python 3中被弃用。在Windows上的Python 2中,某些其他机制似乎将\r\n\n

文档:

为了保留本地行结束符:

with open(file_path, 'rb') as f:
    with line_native_terminated in f:
        ...

二进制模式仍然可以将文件解析为包含in行。 每行都会有文件中的任何终止符。

感谢@katrielalex的answer ,Python的open() doc和iPython实验。


Katrielalex提供了打开和读取一个文件的方式。

但是,您的算法执行的方式会为文件的每一行读取整个文件。 这意味着如果N是文件中行的数量,则读取文件的总量以及计算Levenshtein距离将被执行N * N。 由于您关心的是文件大小,并且不想将它保存在内存中,所以我担心产生的二次运行时间 。 你的算法在O(n ^ 2)类算法中,通常可以通过专门化来改进。

我怀疑你已经知道内存与运行时间的权衡,但也许你会想要调查是否有一种有效的方法来并行计算多个Levenshtein距离。 如果是这样,在这里分享你的解决方案会很有趣。

你的文件有多少行,以及你的算法需要运行什么样的机器(mem和cpu power)以及容忍的运行时间是多少?

代码如下所示:

with f_outer as open(input_file, 'r'):
    for line_outer in f_outer:
        with f_inner as open(input_file, 'r'):
            for line_inner in f_inner:
                compute_distance(line_outer, line_inner)

但问题是如何存储距离(矩阵?),并且您是否可以获得准备处理的outer_line或缓存某些中间结果以供重用等优点。


我强烈建议不要使用默认文件加载,因为它非常慢。 您应该查看numpy函数和IOpro函数(例如numpy.loadtxt())。

http://docs.scipy.org/doc/numpy/user/basics.io.genfromtxt.html

https://store.continuum.io/cshop/iopro/

然后你可以把你的成对操作分成几块:

import numpy as np
import math

lines_total = n    
similarity = np.zeros(n,n)
lines_per_chunk = m
n_chunks = math.ceil(float(n)/m)
for i in xrange(n_chunks):
    for j in xrange(n_chunks):
        chunk_i = (function of your choice to read lines i*lines_per_chunk to (i+1)*lines_per_chunk)
        chunk_j = (function of your choice to read lines j*lines_per_chunk to (j+1)*lines_per_chunk)
        similarity[i*lines_per_chunk:(i+1)*lines_per_chunk,
                   j*lines_per_chunk:(j+1)*lines_per_chunk] = fast_operation(chunk_i, chunk_j) 

将数据加载到数据块中,然后对其执行矩阵操作,要比逐元素地完成数据要快得多!


按照排名顺序的两种高效存储方式(首选最佳) -

  1. 使用with - 来自python 2.5及以上版本
  2. 如果您真的想控制阅读yield ,可以使用yield

with

with阅读大文件是一种很好且高效的pythonic方式。 优点 - 1)文件对象退出执行块后自动关闭。 2) with块内的异常处理。 3)循环内存循环遍历f文件对象。 内部它可以缓冲IO(以优化昂贵的IO操作)和内存管理。

with open("x.txt") as f:
    for line in f:
        do something with data

2.使用yield

有时候可能需要对每次迭代中需要读取的内容进行更细粒度的控制。 在这种情况下使用它和yield 。 请注意,在这种方法中,显式需要在最后关闭文件。

def readInChunks(fileObj, chunkSize=2048):
    """
    Lazy function to read a file piece by piece.
    Default chunk size: 2kB.
    """
    while True:
        data = fileObj.read(chunkSize)
        if not data:
            break
        yield data

f = open('bigFile')
for chuck in readInChunks(f):
    do_something(chunk)
f.close()

陷阱和为了完整起见 - 下面的方法对于阅读大文件来说并不是很好或不够优雅,但请阅读以获得圆润的理解。

在Python中,从文件中读取行的最常用方法是执行以下操作:

for line in open('myfile','r').readlines():
    do_something(line)

但是,当完成这些时, readlines()函数(同样适用于read()函数)将整个文件加载到内存中,然后遍历它。 对于大文件,稍好的方法(前面提到的两种方法最好)是使用fileinput模块,如下所示:

import fileinput

for line in fileinput.input(['myfile']):
    do_something(line)

fileinput.input()调用顺序地读取行,但是在读取之后不会将它们保存在内存中,或者甚至只是这样,因为python中的file是可迭代的。

参考

  1. Python语句

这是在python中读取文件的一种可能方式:

f = open(input_file)
for line in f:
    do_stuff(line)
f.close()

它没有分配一个完整的列表。 它遍历线。


逐行读取大文件的最佳方法是使用python 枚举函数

with open(file_name, "rU") as read_file:
    for i, row in enumerate(read_file, 1):
        #do something
        #i in line of that line
        #row containts all data of that line

#Using a text file for the example
with open("yourFile.txt","r") as f:
    text = f.readlines()
for line in text:
    print line
  • 打开你的文件阅读(r)
  • 阅读整个文件并将每行保存到列表 (文本)
  • 循环显示每行的列表。

例如,如果您想要检查长度大于10的特定行,请使用您已有的功能。

for line in text:
    if len(line) > 10:
        print line




file-read