首页 > 解决方案 > Python加速csv操作

问题描述

有没有办法加快这个 csv 文件操作的处理速度?对于包含 5000 个条目的 csv,它可以正常工作,但是当有 1,000,000 多个条目时,它需要很长时间。

r1 = csv.reader(open('file1.csv'))
r2 = csv.reader(open('file2.csv'))
with open(file3, 'w', newline='') as wf:
    writer = csv.writer(wf)
    entries = []
    first = True

    for child, a, b, c, parent, d in r1:
        if not child and not parent:
            continue
        if first:
            first = False
            continue
        entries.append([parent, child])

    first = True

    for child, _, _, _, parent, _ in r2:
        if not child and not parent:
            continue
        if first:
            first = False
            continue

        entries.append([parent, child])

    for p, c in entries:
        for sp, sc in entries:
            if p == sc:
                break
        else:
            entries.append([p, p])


    writer.writerow(["parent_new", "child_new"])
    writer.writerows(entries)

标题和第一行数据之间还有一个换行符,无论如何要在写入新的csv时删除这个空白行?

标签: pythonpython-3.xperformancecsv

解决方案


你的循环:

    for p, c in entries:
        for sp, sc in entries:
            if p == sc:
                break
        else:
            entries.append([p, p])

将花费二次时间。

它似乎所做的只是编写p不等于任何值的child值。由于这些值来自 CSV 文件,因此必须是字符串,因此是可散列的,您可以将它们(或更具体地说,唯一值)保存在一个集合中:

children = set(child for parent, child in entries)

它需要更多的内存,但你可以这样做

    for p, c in entries:
        if p not in children:
            entries.append([p, p])

所以这应该是线性时间而不是二次时间(因为集合包含测试基本上是恒定时间)。


在更小的一点上,要删除每个输入文件的第一行,而不是使用您的first变量(然后您必须在每次迭代中对其进行测试),只需next(r1)在进入循环之前调用(并丢弃该值) -同样对于r2. 也就是说,不要期望这样做会获得巨大的收益,因为这是代码的线性时间部分。真正重要的是上面提到的 O(n^2) 位。


推荐阅读