【问题标题】:Writing Large CSVs - Memory Usage v. Random Disk Access写入大型 CSV - 内存使用与随机磁盘访问
【发布时间】:2018-06-08 21:17:24
【问题描述】:

我正在使用一组约 1000 个包含 GPS 数据的大型 (700MB+) CSV。时间戳当前位于 UTC 时区,我想将它们更改为 PST。

我编写了一个 Python 脚本来解析文件,用正确的值更新两个时间戳字段,然后将它们写入文件。最初我想尽量减少磁盘写入的次数,所以在每一行我都将更新的行附加到一个字符串中。最后,我对文件进行了一次大写操作。这对小文件按预期工作,但对大文件挂起。

然后我更改了脚本以在处理每一行时写入文件。这有效,不会挂起。

为什么第一个解决方案不适用于大文件,有没有比一次写一行文件更好的方法?

构建一个大字符串:

def correct(d, s):
    # given a directory and a filename, corrects for timezone
    file = open(os.path.dirname(os.path.realpath(sys.argv[0])) + separator() + d + separator() + s)
    contents = file.read().splitlines()

    header = contents[0]

    corrected_contents = header + '\n'

    for line in contents[1:]:
        values = line.split(',')

        sample_date = correct_time(values[1])
        system_date = correct_time(values[-1])

        values[1] = sample_date
        values[-1] = system_date

        corrected_line = ','.join(map(str, values)) + '\n'
        corrected_contents += corrected_line

    corrected_file = os.path.dirname(os.path.realpath(sys.argv[0])) + separator() + d + separator() + "corrected_" + s
    with open (corrected_file, 'w') as text_file:
        text_file.write(corrected_contents)
    return corrected_file

写下每一行:

def correct(d, s):
    # given a directory and a filename, corrects for timezone
    file = open(os.path.dirname(os.path.realpath(sys.argv[0])) + separator() + d + separator() + s)
    contents = file.read().splitlines()

    header = contents[0]

    corrected_file = os.path.dirname(os.path.realpath(sys.argv[0])) + separator() + d + separator() + "corrected_" + s
    with open (corrected_file, 'w') as text_file:
        text_file.write(header + '\n')

        for line in contents[1:]:
            values = line.split(',')

            sample_date = correct_time(values[1])
            system_date = correct_time(values[-1])

            values[1] = sample_date
            values[-1] = system_date

            corrected_line = ','.join(map(str, values)) + '\n'
            text_file.write(corrected_line)

    return corrected_file

【问题讨论】:

标签: python database python-3.x csv


【解决方案1】:

我相信这条线:

   corrected_contents += corrected_line

是罪魁祸首。 IIUC(如果我错了,我相信人们会纠正我)这会分配一个更大的字符串,复制旧内容,然后附加新内容 - 文件中的每一行。随着时间变长,需要复制的内容越来越多,最终您会得到您所观察到的行为。

How do I append one string to another in Python? 有更多关于字符串连接的信息,其中提到显然 CPython 在某些情况下对其进行了优化,并将其从二次变为线性(所以我上面可能错了:你的可能是这样一个优化的情况)。它还提到pypy 没有。所以这也取决于你如何运行你的程序。也可能是因为您的字符串太大而优化不适用(毕竟足以填满一张 CD)。

链接的答案还包含有关解决问题的方法的大量信息(如果确实是问题)。值得一读。

【讨论】:

猜你喜欢
  • 2011-10-21
  • 1970-01-01
  • 2015-11-19
  • 1970-01-01
  • 2017-05-11
  • 1970-01-01
  • 2017-05-30
  • 1970-01-01
  • 2021-09-13
相关资源
最近更新 更多