读取1M记录的数据集并将其复制到Python中的新csv

时间:2014-10-06 05:11:15

标签: python csv mmap

我是python的初学者,我正在尝试使用Memory Map实现逐行将1 M记录的csv复制到新的CSV。

但是按照mmap module具有的规则,它不会映射到空的csv文件。但是我现在遇到的问题要求我在复制数据集时创建一个新的csv文件。

你们可以提出任何指示/帮助吗?这是我的代码:

import os
import mmap
import time
import csv

def mmapUsage():
    start = time.time()
    with open("/home/delhivery/Documents/Python/dataset.csv","r+b") as f:
        mapInput = mmap.mmap(f.fileno(), 0)
        L = list()
        for i in iter(mapInput.readline, ""):
            L.append(i)
        print "List length: ", len(L)
        mapInput.close()
        end = time.time()
        print "Time for completion", end-start


if __name__ == "__main__":

    print "MMap Implementation"
    mmapUsage()

2 个答案:

答案 0 :(得分:1)

如果我正确理解您的问题(与您的其他评论一起使用),您正在通过mmap阅读并解析输入的CSV文件,并且您对任务的这一方面没有任何问题。您的困难在于创建一个包含输入CSV数据(可能已修改)的新CSV文件,即将数据写回 - 特别是使用mmap技术。

你不能mmap一个空文件,但你可以创建一个文件,给它写一些数据,然后像这里所示mmap它,它将输入文件复制到输出文件:

import mmap

with open('dataset.csv', 'r+b') as f, open('outfile.csv', 'w+b') as outfile:
    map_input = mmap.mmap(f.fileno(), 0)
    outfile.write('any old thing will do')
    outfile.flush()                        # important, now you can mmap the file
    map_output = mmap.mmap(outfile.fileno(), 0)
    map_output.resize(map_input.size())    # resize out map to the same size as input file
    # copy all data from map_input to map_output
    # map_output[:] = map_input[:]         # this is the fastest way to copy
    for line in iter(map_input.readline, ''):
        map_output.write(line)
    map_output.close()
    map_input.close()

请注意,如果您修改输入CSV数据,那么您的任务将退化为一个简单的文件复制练习,您应该访问操作系统级命令(例如* nix中的cp ),或使用shtuil.copy()等内容复制文件。

如果要修改传入数据,则需要担心数据的修改后长度。您需要处理输出数据大于输入数据的情况,并确保底层映射足够大以处理所有数据。处理完毕后,您可以再次使用数据的最终长度调用map_output.resize()

使用mmap时显然还有很多需要考虑的问题,当您实际解析 CSV数据(代码忽略)时,处理数据,转换回CSV,以及处理了mmap中存在的数据长度问题,你最好只使用csv模块。在性能方面,csv模块会变慢,但是您的应用程序是否真的需要以代码复杂性为代价来提高性能?

答案 1 :(得分:0)

如果您只想执行每行解析,只要您在一行中执行一行,就可以在标准Python中处理非常大的文件。我有点不确定这是不是你想要的,但是这个代码在千兆字节大小的文件上工作正常:

infile='input.csv'
outfile='out.csv'

with open(infile,'r') as in_f, open(outfile,'w') as out_f:
    line_counter=0
    for line in in_f:
        # Perform some optional parsing
        line_counter+=1
        print >> out_f,line, # Write out your (parsed) line

print "%d lines in input file" % line_counter

此解决方案不使用mmap,但是从上面的评论来看,这并非真正的要求。