python实际应用5-从大文件中读取指定大小或记录数

@2019年1月17日

  • 背景

    由于工作性质,经常面对不同的问题,某些场景下SQL+Excel、常用办公软件不能处理,这时到网上找一些案例,自己动手用python处理。后续,借此博客记录比较典型的处理过程。
    后续,陆续实际处理的问题,如

  • 合并PDF(https://blog.csdn.net/weixin_44230447/article/details/85231757)

  • 拆分PDF(https://blog.csdn.net/weixin_44230447/article/details/85232235)

  • 敏感字段MD5脱(https://blog.csdn.net/weixin_44230447/article/details/85233266)

  • 从非架构化的大文本文件中提取指定条件的记录(https://blog.csdn.net/weixin_44230447/article/details/85233565)

  • 从大文件中读取指定大小或记录数

  • 需求
    为什么要从“从大文件中读取指定大小或记录数”,最近年底要测试一个服务器与各分公司之间的网速,需要一系列测试基准文件,如100MB、1GB、5GB等固定大小的文件,如100条和1000万条的记录。手里正好有一个6GB大小2000余万的数据。在“从非架构化的大文本文件中提取指定条件的记录”中的程序基础上,修改运行后,发现readlines 方法无法一口读下上GB的文件,readline、read()也不好用,具体问题见上一篇博客,最后用如下方法解决。

  • Python 程序
    程序1:从大文件中读取指定数量记录后写入一个文件。
    其中,第9~10行是关键,一行行读入。

#导入原始文件,抽取部分记录
#load data from file
#从txt文件导入数据,
def load_data(in_filename,out_filename,skip,out_extract_rows):
    out_file= open(out_filename,'a')
    i=0
    j=0
    k=0
    with open(in_filename, 'r') as in_file:
        for line in in_file:
            # 前8行skip
            i = i + 1
            #print(i)
            if i >= skip:
                # lineArr = line.strip().split('|')  # strip() 方法用于移除字符串头尾指定的字符(默认为空格)
                #print("This line is ", line)
                j = j + 1
                if j%10000 ==0 :
                    k=k+1
                    print("The Program has extracted ",k," 万行")

                out_file.write(line)
            if j == out_extract_rows:
                break
            # do something...
    return j

file_path="D:/测试样例/"
short_file_name = "用户主商品.tsv"
full_file_name = file_path + short_file_name
out_file_name = file_path + "数据样例100万条.tsv"
skip_lines=0
extract_rows=10000001 # 含表头的一行

out_rows = load_data(full_file_name,out_file_name,skip_lines,extract_rows)

print("本次操作从第",skip_lines+1,"行开始提取了",out_rows,"条记录")
print('-'*50)
#------------------ End of python --------------------------------------

程序2:从大文件中读取指定大小后写入一个文件。
其中,这个程序在程序1基础上修改,中间试过read() 不仅容易出现内存错误,而且对于每行记录非定长的情况,最后一行会出现不完整的问题。因此还是上述方法。

#导入原始文件,抽取指定大小的记录,且完整取出每行。
#load data from file
#从txt文件导入数据,
def load_data(in_filename,out_filename,skip,out_extract_max_size):
    out_file= open(out_filename,'a')
    i=0
    j=0
    k=0
    l_size=0
    with open(in_filename, 'r') as in_file:
        for line in in_file:
            # 前8行skip
            i = i + 1
            #print(i)
            if i >= skip:
                # lineArr = line.strip().split('|')  # strip() 方法用于移除字符串头尾指定的字符(默认为空格)
                #print("This line is ", line)
                j = j + 1
                l_size = l_size + len(line)
                if j%10000 ==0 :
                    k=k+1
                    print("The Program has extracted ",k," 万行")

                out_file.write(line)
            if l_size >= out_extract_max_size:
                break
            # do something...
    return j,l_size

#打印出来看一下数据集大小
file_path="D:/测试样例/"
short_file_name = "用户主商品.tsv"
full_file_name = file_path + short_file_name
out_file_name = file_path + "04 数据样例5GB.tsv"
skip_lines=0
extract_max_size=5*1024*1024*1024  # 1024*1024 equal 1MB
out_rows,out_file_size = load_data(full_file_name,out_file_name,skip_lines,extract_max_size)

print("本次操作从第",skip_lines+1,"行开始提取了",out_rows,"条记录,文件为",out_file_size/(1024*1024),'MB.')
print('-'*50)
#------------------ End of python --------------------------------------

这简短两行,通过with 还实现了错误异常处理,代码非常精简。mark

    with open(in_filename, 'r') as in_file:
        for line in in_file:

有了这些标准大小和记录数的文件,后续对各种测试就有了一个基准。

你可能感兴趣的:(综合,Python)