【问题标题】:Splitting a CSV into two files by repeated cells Python通过重复的单元格 Python 将 CSV 拆分为两个文件
【发布时间】:2014-11-30 05:32:08
【问题描述】:

在第一个实例之后重复行 ID(奇怪地放置在第 8 列,即行 [7])时,我想将这些行写入第二个文件。我尝试过的代码非常慢——它是一个 40 列的 CSV,大约有一百万行。这就是我所拥有的:

def in_out_repsplit(inf, outf1, outf2):
    outf1 = csv.writer(open(outf1, 'wb'), delimiter=',', lineterminator='\n')
    outf2 = csv.writer(open(outf2, 'wb'), delimiter=',', lineterminator='\n')
    inf1 = csv.reader(open(inf, 'rbU'), delimiter=',')
    inf1.next()
    checklist = []
    for row in inf1:
        id_num = str(row[7])
        if id_num not in checklist:
            outf1.writerow(row)
            checklist.append(id_num)
        else:
            outf2.writerow(row)

【问题讨论】:

    标签: python python-2.7 csv


    【解决方案1】:

    in 运算符在 Python list() 上进行线性搜索,因为您只需要成员资格测试,Python 的 set() 是一个更合适的结构,具有平均恒定时间成员资格测试。对于具有一百万行的 CSV,这个小改动应该会大大加快速度。

    def in_out_repsplit(inf, outf1, outf2):
        outf1 = csv.writer(open(outf1, 'wb'), delimiter=',', lineterminator='\n')
        outf2 = csv.writer(open(outf2, 'wb'), delimiter=',', lineterminator='\n')
        inf1 = csv.reader(open(inf, 'rbU'), delimiter=',')
        inf1.next()
        checklist = set()
        for row in inf1:
            id_num = str(row[7])
            if id_num not in checklist:
                outf1.writerow(row)
                checklist.add(id_num)
            else:
                outf2.writerow(row)
    

    另外,如果id_num 是一个整数,请使用int 而不是str。如果 id_num 在 [0...N] 范围内(其中 N 合理地接近百万行),您可以使用布尔值列表并获得更快的查找。

        ...
        checklist = [False] * (MAXID + 1)
        for row in inf1:
            id_num = int(row[7])
            if not checklist[id_num]:
                outf1.writerow(row)
                checklist[id_num] = True
            else:
                outf2.writerow(row)
    

    【讨论】:

    • 哇。为了纯粹的信息,这将我的代码时间从大约 45 分钟更改为 6.0 秒。 Python 太棒了。
    • 我认为这是一个很好的答案,直到我看到使用可能有一百万个条目的布尔值列表的建议......
    • @martineau 你能解释一下为什么吗?在这种情况下,布尔列表对于存储和时间都是最有效的。该集合还将添加一百万个项目。
    • 因为布尔值列表,它是整数的子类型,是一种公然的空间浪费,当拥有一个常规ints 的列表并执行类似this 的操作非常容易反而。虽然这样做需要计算索引和偏移量,但这只是类似divmod() 的操作,因此在访问各个位时只会有非常小的速度损失。 set 是否同样糟糕取决于是否遇到所有可能的id_num
    • @rpattiso: ...另请参阅this answer,它将位图存储在单个 Python 任意长整数中。
    猜你喜欢
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 2015-07-28
    • 1970-01-01
    相关资源
    最近更新 更多