【问题标题】:Replace value from CSV with Python用 Python 替换 CSV 中的值
【发布时间】:2014-03-03 16:18:45
【问题描述】:

我必须替换大型 CSV 文件中的值,并决定使用 Python 作为我要使用的编程语言。

我需要更改的值是逗号分隔 CSV 中每一行的第一个值:

ToReplace, a1, a2, ..., aN
1, ab, cd, ..., xy
80, ka, kl, ..., df

它总是一个数字,但数字的数量不固定。

我目前有两个想法:逐行处理数据和...

  1. 使用正则表达式匹配数字
  2. 使用 CSV 组件解析行

由于我对 Python 很陌生,所以我想到了一些问题:

  • 考虑到文件的大小(> 50GB;~ 1000 万行),哪种方法更快?
  • 如何在不浪费大量资源的情况下实现它?

【问题讨论】:

  • 旁白:50 GB 的文件太大,无法以 CSV 等平面格式保存。切换到数据库或至少将文件拆分为更易于管理的文件(例如 500 个 100MB 文件)
  • 这正是我需要处理文件的原因,以便我可以快速干净地将其放入数据库中

标签: python regex csv


【解决方案1】:

如果要替换始终包含数字的第一列,则可以使用字符串方法而不是更通用的 csv 模块,以避免解析整行:

#!/usr/bin/env python

def main():
    with open('50gb_file', 'rb') as file, open('output', 'wb') as output_file:
        for line in file:
            number, sep, rest = line.partition(b',')
            try:
                number = int(number)*2 #XXX replace number here
            except ValueError:
                pass # don't replace the number
            else:
                line = bytes(number) + sep + rest
            output_file.write(line)

main()

【讨论】:

    【解决方案2】:

    您可以将第二个参数传递给 Python 的 split 方法,以便获得第一个匹配项,将其替换为您想要的任何内容,然后重新加入单个字符串,如下所示:

    import logging
    
    with open('example.csv', 'rb') as infile, \
            open('result.csv', 'wb') as outfile:
        for line in in file:
            try:
                number, rest = line.split(',', 1)
                number = 'blob'
                outfile.write(','.join([number, rest]))
            except ValueError:
                logging.error('The following line had no separator: %s', line)
    

    对于 1000 万行,在 2.4 GHz 和 8 Gb RAM 的 2 个内核上,我得到以下时间:

    $ time python example.py
    
    real    0m20.771s
    user    0m20.336s
    sys 0m0.369s
    

    【讨论】:

    • 如果一行没有逗号,number, rest = line.split(',', 1) 会失败。对两个文件使用兼容的文件模式(二进制文件或文本文件)。
    • @J.F.Sebastian :你是对的,我编辑了我的答案以改进这两个方面。但是,我更喜欢记录错误,因为“错误永远不应该默默地传递”。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2014-02-26
    • 2019-10-15
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    相关资源
    最近更新 更多