在写入CSV时将列添加到CSV

时间:2013-11-26 18:20:31

标签: python parsing csv

我正在写一篇csv中的以下数据:

name first file parsed                    
STEP ID  ELEMENT_ID  Fatigue SW  Fatigue F1  Fatigue F3
Step 10  10000       1.30E-07    1.51E-06    2.15E-06

当我完成解析第一个文件并开始第二个文件时,我想添加更多列,如下所示:

name first file parsed                                   name first file parsed
STEP ID  ELEMENT_ID  Fatigue SW  Fatigue F1  Fatigue F3  Fatigue SW  Fatigue F1  Fatigue F3
Step 10  10000       1.30E-07    1.51E-06    2.15E-06    1.30E-07    1.51E-06    2.15E-06

我正在阅读的文件是2Gb,因此我负担不起创建列表,我需要在解析时编写。

有什么建议吗?

2 个答案:

答案 0 :(得分:4)

您无法将列添加到现有CSV文件中;你不得不重写整个文件,我很害怕。

您可以使用以下上下文管理器更轻松地替换文件:

from contextlib import contextmanager
import io
import os


@contextmanager
def inplace(filename, mode='r', buffering=-1, encoding=None, errors=None,
            newline=None, backup_extension=None):
    """Allow for a file to be replaced with new content.

    yields a tuple of (readable, writable) file objects, where writable
    replaces readable.

    If an exception occurs, the old file is restored, removing the
    written data.

    mode should *not* use 'w', 'a' or '+'; only read-only-modes are supported.

    """

    # move existing file to backup, create new file with same permissions
    # borrowed extensively from the fileinput module
    if set(mode) & set('wa+'):
        raise ValueError('Only read-only file modes can be used')

    backupfilename = filename + (backup_extension or os.extsep + 'bak')
    try:
        os.unlink(backupfilename)
    except os.error:
        pass
    os.rename(filename, backupfilename)
    readable = io.open(backupfilename, mode, buffering=buffering,
                       encoding=encoding, errors=errors, newline=newline)
    try:
        perm = os.fstat(readable.fileno()).st_mode
    except OSError:
        writable = open(filename, 'w' + mode.replace('r', ''),
                        buffering=buffering, encoding=encoding, errors=errors,
                        newline=newline)
    else:
        os_mode = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
        if hasattr(os, 'O_BINARY'):
            os_mode |= os.O_BINARY
        fd = os.open(filename, os_mode, perm)
        writable = io.open(fd, "w" + mode.replace('r', ''), buffering=buffering,
                           encoding=encoding, errors=errors, newline=newline)
        try:
            if hasattr(os, 'chmod'):
                os.chmod(filename, perm)
        except OSError:
            pass
    try:
        yield readable, writable
    except Exception:
        # move backup back
        try:
            os.unlink(filename)
        except os.error:
            pass
        os.rename(backupfilename, filename)
        raise
    finally:
        readable.close()
        writable.close()
        try:
            os.unlink(backupfilename)
        except os.error:
            pass

将此项与csv模块一起使用以添加列:

with inplace(csvfilename, 'rb') as (infh, outfh):
    reader = csv.reader(infh)
    writer = csv.writer(outfh)

    for row in reader:
        row += ['new', 'column']
        writer.writerow(row)

答案 1 :(得分:0)

  1. 定义一个代表原始数据行的类(例如OriginalData)。
  2. 定义从第一个类派生的第二个类,并包含每个新列的属性(例如NewData)。
  3. 在NewData上创建一个构造函数,该构造函数将OriginalData作为参数。让它将OriginalData中的数据复制到自身。
  4. 在NewData上重载ToString(),以便它以您希望它在目标文件中显示的格式返回一个字符串。
  5. 在迭代这些行时,将它们读入OriginalData实例。
  6. 加载originalData实例后,将数据复制到NewData实例中,并填充新属性以包含数据。
  7. 通过调用NewData的ToString()方法将数据从NewData写入目标文件。