【问题标题】:Improve speed for csv.reader/csv.writer in the csv module提高 csv 模块中 csv.reader/csv.writer 的速度
【发布时间】:2015-01-01 19:40:57
【问题描述】:

我正在做一个非常简单的操作;打开一个 csv 文件,删除第一列,然后写入一个新文件。以下代码运行良好,但在我的 700 MB 文件上需要 50-60 秒:

import csv
from time import time
#create empty output file
f = open('testnew.csv',"w")
f.close()
t = time()
with open('test.csv',"rt") as source:
    rdr= csv.reader( source )
    with open('testnew.csv',"a") as result:
        wtr= csv.writer( result )
        for r in rdr:
            del r[0]
            _ = wtr.writerow( r )

print(round(time()-t))

相比之下,以下 shell 脚本在 7-8 秒内完成相同的操作:

START_TIME=$SECONDS
cut -d',' -f2- < test.csv > testnew.csv
echo $(($SECONDS - $START_TIME))

有没有办法在 Python 中获得可比的性能?

【问题讨论】:

    标签: performance csv python-3.x


    【解决方案1】:

    如果我理解正确,shell 脚本只是在第一个, 处拆分行,不管它是否用引号括起来,然后写出第二部分。 (如果没有,,我不知道shell 脚本会做什么。) csv 方法做了much 更多,这对你没用。要在 python 中执行与 shell 相同的操作,请跳过 csv 模块。

    for line in source:
       parts = line.split(',', maxsplit=1)
       source.write(parts[len(parts)-1])
    

    这会按原样传递不带逗号的行。它在逗号后留下空格(我不知道cut 是做什么的。如果您不希望这样做,您可以使用re.split 而不是line.split 或在关闭) 之前添加.lstrip()最后一行。

    【讨论】:

    • 我用相关的with open 语句包装了您的代码示例,并将source.write 替换为_ = result.write。生成的代码仍然比@histrio 的解决方案多花 30-40% 的时间。
    • 我的代码和 histrio 的唯一重要区别是处理行中没有 ',' 的情况。如果您确定这不会发生,或者如果确实发生了异常,那么请使用稍微简单的代码。
    【解决方案2】:

    您的 bash 脚本不解析 csv 文件,仅拆分和剪切。所以,在 python 中我们也可以这样做:

    with open('test.csv',"r") as source:
        with open('testnew.csv',"w") as result:
            for l in source:
                _, tail = l.split(',', 1)
                result.write(tail)
    

    我的简单分析(4Mb 文件):

    • bash - 193 毫秒
    • python csv 解析 - 2391 毫秒
    • python 字符串拆分 - 620 毫秒

    出于某种原因,Python 2 更快:

    • bash - 193 毫秒
    • python csv 解析 - 1471 毫秒
    • python 字符串拆分 - 373 毫秒

    【讨论】:

    • 我得到了可比较的结果,但在 result.write(tail) 之前有一个 _= 以防止它打印每行上的字符数。所以对于我的原始文件,它仍然需要两倍于 bash 的时间。
    • 您可以为此任务编写 C 扩展 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-08
    • 1970-01-01
    • 2016-01-23
    • 1970-01-01
    • 2013-01-10
    相关资源
    最近更新 更多